gpt4 book ai didi

nhibernate - 流畅的 NHibernate 自动映射 : How to custom subclass table name and key column name?

转载 作者:行者123 更新时间:2023-12-04 01:47:03 24 4
gpt4 key购买 nike

我想以前肯定有人问过这个问题,但我用谷歌搜索了一个小时但找不到答案。

假设我有以下 2 个模型:

public class Organism
{
public virtual int Id { get; private set; }
}

public class Animal : Organism
{
}

我希望 Fluent NHibernate 为我创建以下表格:
OrganismTable
OrganismId

AnimalTable
AnimalId

这可以通过使用手动映射轻松实现:
public class OrganismMappinig : ClassMap<Organism>
{
public OrganismMappinig()
{
Table("OrganismTable");
Id(x => x.Id).Column("OrganismId");
}
}

public class AnimalMapping : SubclassMap<Animal>
{
public AnimalMapping()
{
Table("AnimalTable");
KeyColumn("AnimalId");
}
}

但是我无法使用自动映射获得相同的结果。我尝试添加以下约定:
public class TableNameConvension : IClassConvention, IClassConventionAcceptance
{
public void Apply(IClassInstance instance)
{
instance.Table(instance.EntityType.Name + "Table");
}

public void Accept(IAcceptanceCriteria<IClassInspector> criteria)
{
criteria.Expect(x => x.TableName, Is.Not.Set);
}
}

public class PrimaryKeyNameConvention : IIdConvention
{
public void Apply(IIdentityInstance instance)
{
instance.Column(instance.EntityType.Name + "Id");
}
}

它创建了这两个表:
OrganismTable (correct)
OrganismId (correct)

Animal (wrong, should be "AnimalTable")
Organism_id (wrong, should be "AnimalId")

我还尝试添加:
public class ForeignKeyColumnNameConvention : ForeignKeyConvention
{
protected override string GetKeyName(Member property, Type type)
{
if (property == null)
return type.Name + "Id";

return property.Name + "Id";
}
}

它创建了这两个表:
OrganismTable (correct)
OrganismId (correct)

Animal (wrong, should be "AnimalTable")
OrganismId (wrong, should be "AnimalId")

我还尝试添加:
public class AnimalOverride : IAutoMappingOverride<Animal>
{
public void Override(AutoMapping<Animal> mapping)
{
mapping.Table("AnimalTable");
mapping.Id(x => x.Id).Column("AnimalId");
}
}

它创建了以下表:
OrganismTable (correct)
OrganismId (correct)

AnimalTable (correct)
OrganismId (wrong, should be "AnimalId")

这正确地将表名设置为“AnimalTable”(但这需要太多的手动输入,如果有可以得到相同结果的约定会很棒),但未能将键列名设置为“AnimalId”。

下面是我的其余代码:
class Program
{
static void Main(string[] args)
{
ISessionFactory sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration
.MsSql2008.ConnectionString(connectionString)
.ShowSql())
.Mappings(m => m.AutoMappings.Add(
AutoMap.Assemblies(typeof(Organism).Assembly)
.Conventions.AddAssembly(typeof(Program).Assembly)
.UseOverridesFromAssembly(typeof(Program).Assembly)))
.ExposeConfiguration(BuildSchema)
.BuildConfiguration()
.BuildSessionFactory();
}

static void BuildSchema(Configuration cfg)
{
new SchemaExport(cfg).Create(false, true);
}
}

有任何想法吗?谢谢。

最佳答案

当 FluentNHibernate 是自动映射时,它使用 table-per-concrete-class 来映射继承层次结构。由于 Organism 和 Animal 都是具体类型,因此它生成了两个表,OrganismTable 和 AnimalTable。 OrganismTable 存储所有有机体共有的所有属性。 AnimalTable 只存储 Animal 子类添加的属性。 AnimalTable上的PK也是OrganismTable的FK。因此它会受到您的 FK 约定的影响。请注意,PKNameConvention 仅适用于 Organism 而不是 Animal。同样 FKColumnNameConvention 只能由 Animal 调用。由于 Animal FK 仅在内部用于 Hook 继承层次结构,因此该属性为 null。因此,您将获得 OrganismId 作为 FK 名称。要设置此 PK/FK,您需要使用 IJoinedSubclassConvention。 (为了完整起见,我已经包含了您的 TableNameConvention 和 PrimaryKeyNameConvention。)

public class TableNameConvension : IClassConvention, IClassConventionAcceptance {
public void Apply(IClassInstance instance) {
instance.Table(instance.EntityType.Name + "Table");
}

public void Accept(IAcceptanceCriteria<IClassInspector> criteria) {
criteria.Expect(x => x.TableName, Is.Not.Set);
}
}
public class PrimaryKeyNameConvention : IIdConvention {
public void Apply(IIdentityInstance instance) {
instance.Column(instance.EntityType.Name + "Id");
}
}
public class JoinedSubclassIdConvention : IJoinedSubclassConvention
{
public void Apply(IJoinedSubclassInstance instance) {
instance.Table(instance.EntityType.Name + "Table");
instance.Key.Column(instance.EntityType.Name + "Id");
}
}

这会产生:
OrganismTable
OrganismId

AnimalTable
AnimalId

使用从 AnimalTable.AnimalId 到 OrganismTable.OrganismId 的 FK。

请注意,由于查询实体时需要的连接数量,table-per-concrete-class 不是我首选的继承映射。通常每个子类表或每个类层次表是更好的选择。我将把它作为练习让读者调查 inheritance strategies 上 NHibernate 文档中的差异。 .

关于nhibernate - 流畅的 NHibernate 自动映射 : How to custom subclass table name and key column name?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5453625/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com