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 列
  1. PersonId 对于 References(x => x.Person)
  2. 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();