NHibernate 单向一对多关系不保存外键

NHibernate unidirectional one-to-many relationship not saving foreign key

我是 NHibernate 的新手,我正在创建一个简单的场景来测试框架功能。

我要基本实体:

public class School : BaseEntity
{
    public virtual string Code { get; set; }
    public virtual string Name { get; set; }
}

public class Student : BaseEntity
{
    public virtual string Name { get; set; }
    public virtual string Surname { get; set; }
    public virtual string Email { get; set; }
    public virtual School School { get; set; }
}

继承自一个简单的基础 class:

public abstract class BaseEntity
{
    public virtual int Id { get; protected set; }
}

比起我使用 FluentNhibernate 映射实体的方式:

return Fluently.Configure()
   .Database(MsSqlConfiguration.MsSql2012.ConnectionString(
        c => c.FromConnectionStringWithKey("DataModel")))
   .Mappings(m => m.AutoMappings
       .Add(AutoMap.AssemblyOf<BaseEntity>()
       .Where(t => t.Namespace == "MyApp.Models"))
       .IgnoreBase<BaseEntity>()
       .Override<User>(map =>
       {
           map.Table("Users");
           map.HasOne<School>(u => u.School).ForeignKey("SchoolId");
       })
       .Override<School>(map =>
       {
           map.Table("Schools");
       })
   ))
   .BuildSessionFactory();

我的测试代码很简单:

using (var transaction = DbSession.BeginTransaction())
{
    Student u1 = DbSession.Get<Student>("user-id");
    School s1 = DbSession.Get<School>("school-id");

    u1.School = s1; // updating the associated school

    DbSession.SaveOrUpdate(u1);

    transaction.Commit(); // !!! the foreign key is not updated
}

检查学生 table,该行未使用新学校 ID 更新。

那么,我的代码有什么问题?我的映射中是否有错误(或缺失)?

属于SchoolStudentmany-to-one关系。

5.1.11. many-to-one

An ordinary association to another persistent class is declared using a many-to-one element. The relational model is a many-to-one association. (It's really just an object reference.)

它的流畅版本是.References()

References / many-to-one

References is for creating many-to-one relationships between two entities, and is applied on the "many side." You're referencing a single other entity, so you use the References method. #HasMany / one-to-many is the "other side" of the References relationship, and gets applied on the "one side."

Let's map a relationship between a book and its author.

public class Book
{
  public Author Author { get; set; }
}

public class Author
{
  public IList<Book> Books { get; set; }
}

In domain terms, we have an Author which may be associated with any number of Books, and Books, each of which can be associated with a single Author.

In database terms, we'd have a book table with a foreign key column referencing the primary key of an author table.

To create the references relationship in your Book #ClassMap, add the following call in the BookMap constructor:

References(x => x.Author);

换句话说,如果我们需要many-to-one关系用fluent映射,我们不能使用.HasOne()而是.References ()

//map.HasOne<School>(u => u.School).ForeignKey("SchoolId");
map.References(u => u.School, "SchoolId");

要全面了解 .References() API,请阅读本文的后半部分 (前半部分是代码映射,后半部分是与 fluent 的比较) :

mapping by code - Many-to-One 亚当·巴尔

注意 - 什么是 .HasOne()one-to-one)场景问题可以找到 here