Fluent NHibernate 引用映射的不一致行为
Inconsistent Behaviour for Fluent NHibernate Reference Mapping
我一直在使用 Fluent NHibernate,我注意到在重载默认外键约定时使用引用时我认为是不一致的行为。
遵循 NHibernate 的约定,我将有一个外键名称,其中包含一个 _
,并且每个记录集中有一个记录集,记录之间具有外键关系。例如:
Person
Id - Integer - PK
Name - String/NVarchar
Address
Id - Integer - PK
LineOne - String/NVarchar
Person_Id - Integer - FK
使用以下代码,这一切都按预期工作
void Main()
{
using var factory = Fluently.Configure()
.Database(MsSqliteConfiguration.Standard.UsingFile("C:\Temp\Test.db"))
.Mappings(mappings =>
{
mappings
.FluentMappings
.AddFromAssemblyOf<AddressClassMap>();
})
.BuildSessionFactory();
using var session = factory.OpenSession();
session.Query<Address>().ToList().Dump();
}
public class PersonClassMap : ClassMap<Person>
{
public PersonClassMap()
{
Table("Person");
Id(x => x.Id);
}
}
public class AddressClassMap : ClassMap<Address>
{
public AddressClassMap()
{
Table("Address");
Id(x => x.Id);
Map(x => x.PersonId).Column("Person_Id");
References(x => x.Person).Not.LazyLoad();
}
}
public class Person
{
public virtual int Id { get; set; }
}
public class Address
{
public virtual int Id { get; set; }
public virtual int PersonId { get; set; }
public virtual Person Person { get; set; }
}
请问return预期数据:
但是,如果我不遵循惯例并且没有下划线,就像这样:
Person
Id - Integer - PK
Name - String/NVarchar
Address
Id - Integer - PK
LineOne - String/NVarchar
PersonId - Integer - FK
我希望,像下面的代码一样为外键添加一个约定,会产生相同的效果,但没有下划线也能工作:
void Main()
{
using var factory = Fluently.Configure()
.Database(MsSqliteConfiguration.Standard.UsingFile("C:\Temp\Test.db"))
.Mappings(mappings =>
{
mappings
.FluentMappings
.AddFromAssemblyOf<AddressClassMap>()
.Conventions.Add(FluentNHibernate.Conventions.Helpers.ForeignKey.EndsWith("Id"));
})
.BuildSessionFactory();
using var session = factory.OpenSession();
session.Query<Address>().ToList().Dump();
}
public class PersonClassMap : ClassMap<Person>
{
public PersonClassMap()
{
Table("Person");
Id(x => x.Id);
}
}
public class AddressClassMap : ClassMap<Address>
{
public AddressClassMap()
{
Table("Address");
Id(x => x.Id);
Map(x => x.PersonId);
References(x => x.Person).Not.LazyLoad();
}
}
public class Person
{
public virtual int Id { get; set; }
}
public class Address
{
public virtual int Id { get; set; }
public virtual int PersonId { get; set; }
public virtual Person Person { get; set; }
}
但是这会产生异常:
我希望这段代码可以让我不必遵循使用“_”的约定,但如果没有遇到异常,情况似乎并非如此。我希望在第一个示例中,它的工作方式应该与第二个示例相同。
我希望的行为是让代码像我给出的第一个示例一样,但不必遵循 NHibernate 的约定。这将使我能够在实体上设置外键 ID,并允许我使用此外键 属性.
保持关系
我不确定我是否做错了什么或错过了什么?我已经尝试了 属性ref 等各种其他选项,看看它是否会产生我期望的行为,但到目前为止无济于事。
在第一个示例中没有按预期工作。它在 Address
table 中为 person:
创建了 2 列
PersonId
对于 References(x => x.Person)
Person_Id
对于 Map(x => x.PersonId).Column("Person_Id")
)
在第二个示例中,您试图多次映射同一列,因此出现异常。 NHibernate 不知道如何为重复列构建 INSERT/UPDATE 语句。您需要将重复项标记为只读属性(如 xml 映射中的 insert="false" update="false"
)。类似于:
Map(x => x.PersonId);
References(x => x.Person).Not.LazyLoad().ReadOnly();
我一直在使用 Fluent NHibernate,我注意到在重载默认外键约定时使用引用时我认为是不一致的行为。
遵循 NHibernate 的约定,我将有一个外键名称,其中包含一个 _
,并且每个记录集中有一个记录集,记录之间具有外键关系。例如:
Person
Id - Integer - PK
Name - String/NVarchar
Address
Id - Integer - PK
LineOne - String/NVarchar
Person_Id - Integer - FK
使用以下代码,这一切都按预期工作
void Main()
{
using var factory = Fluently.Configure()
.Database(MsSqliteConfiguration.Standard.UsingFile("C:\Temp\Test.db"))
.Mappings(mappings =>
{
mappings
.FluentMappings
.AddFromAssemblyOf<AddressClassMap>();
})
.BuildSessionFactory();
using var session = factory.OpenSession();
session.Query<Address>().ToList().Dump();
}
public class PersonClassMap : ClassMap<Person>
{
public PersonClassMap()
{
Table("Person");
Id(x => x.Id);
}
}
public class AddressClassMap : ClassMap<Address>
{
public AddressClassMap()
{
Table("Address");
Id(x => x.Id);
Map(x => x.PersonId).Column("Person_Id");
References(x => x.Person).Not.LazyLoad();
}
}
public class Person
{
public virtual int Id { get; set; }
}
public class Address
{
public virtual int Id { get; set; }
public virtual int PersonId { get; set; }
public virtual Person Person { get; set; }
}
请问return预期数据:
但是,如果我不遵循惯例并且没有下划线,就像这样:
Person
Id - Integer - PK
Name - String/NVarchar
Address
Id - Integer - PK
LineOne - String/NVarchar
PersonId - Integer - FK
我希望,像下面的代码一样为外键添加一个约定,会产生相同的效果,但没有下划线也能工作:
void Main()
{
using var factory = Fluently.Configure()
.Database(MsSqliteConfiguration.Standard.UsingFile("C:\Temp\Test.db"))
.Mappings(mappings =>
{
mappings
.FluentMappings
.AddFromAssemblyOf<AddressClassMap>()
.Conventions.Add(FluentNHibernate.Conventions.Helpers.ForeignKey.EndsWith("Id"));
})
.BuildSessionFactory();
using var session = factory.OpenSession();
session.Query<Address>().ToList().Dump();
}
public class PersonClassMap : ClassMap<Person>
{
public PersonClassMap()
{
Table("Person");
Id(x => x.Id);
}
}
public class AddressClassMap : ClassMap<Address>
{
public AddressClassMap()
{
Table("Address");
Id(x => x.Id);
Map(x => x.PersonId);
References(x => x.Person).Not.LazyLoad();
}
}
public class Person
{
public virtual int Id { get; set; }
}
public class Address
{
public virtual int Id { get; set; }
public virtual int PersonId { get; set; }
public virtual Person Person { get; set; }
}
但是这会产生异常:
我希望这段代码可以让我不必遵循使用“_”的约定,但如果没有遇到异常,情况似乎并非如此。我希望在第一个示例中,它的工作方式应该与第二个示例相同。
我希望的行为是让代码像我给出的第一个示例一样,但不必遵循 NHibernate 的约定。这将使我能够在实体上设置外键 ID,并允许我使用此外键 属性.
保持关系我不确定我是否做错了什么或错过了什么?我已经尝试了 属性ref 等各种其他选项,看看它是否会产生我期望的行为,但到目前为止无济于事。
在第一个示例中没有按预期工作。它在 Address
table 中为 person:
PersonId
对于References(x => x.Person)
Person_Id
对于Map(x => x.PersonId).Column("Person_Id")
)
在第二个示例中,您试图多次映射同一列,因此出现异常。 NHibernate 不知道如何为重复列构建 INSERT/UPDATE 语句。您需要将重复项标记为只读属性(如 xml 映射中的 insert="false" update="false"
)。类似于:
Map(x => x.PersonId);
References(x => x.Person).Not.LazyLoad().ReadOnly();