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

本文关键字:保存 关系 一对多 NHibernate | 更新日期: 2023-09-27 18:04:21

我是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; }
}

继承了一个简单的基类:

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
}

检查student表,该行没有更新新的学校id。

那么,我的代码出了什么问题?在我的映射中有什么不正确的(或缺失的)吗?

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

属于SchoolStudent是一个 many-to-one 关系

5.1.11。多对一的

与另一个持久类的普通关联使用多对一元素声明。关系模型是一个多对一的关联。(它实际上只是一个对象引用。)

其流畅版本为 .References()

引用/多对一

References用于在两个实体之间创建多对一关系,并应用于"多端"。你引用了一个单独的其他实体,所以你使用References方法。#HasMany/一对多是引用关系的"另一边",并被应用于"一边"。

让我们映射一本书和作者之间的关系。

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

在域术语中,我们有一个Author,它可以与任意数量的book相关联,而Books,每一个都可以与一个Author相关联。

在数据库术语中,我们有一个带有外键列的book表,该列引用author表的主键。

要在book# ClassMap中创建引用关系,在BookMap构造函数中添加以下调用:

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 by Adam Bar

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