如何使用NHibernate/Fluent NHibernate将两张数据库表记录整合到单个视图
问题修正与实现步骤
你当前的代码存在两处核心配置错误,先修正后即可实现Client与Phone关联数据的查询、绑定:
- 关系类型定义错误:从表结构可知一个Client可以对应多条Phone记录,属于典型一对多关系,但你当前Clients类中只定义了单个Phones类型属性,不符合业务逻辑
- 映射配置错误:
References用于映射多对一/一对一的从属关系,要求外键在当前实体对应表中,但Client表没有ClientID字段,该字段实际在Phones表中,配置逻辑完全错误
第一步:修正POCO类定义
public class Clients { public virtual int ID { get; set; } public virtual string Name { get; set; } public virtual string Email { get; set; } public virtual DateTime? BirthDate { get; set; } // 表结构中BirthDate可空,对应改为可空类型避免查询报错 public virtual IList<Phones> Phones { get; set; } = new List<Phones>(); // 改为集合类型对应多条电话记录 } // Phones类无需修改,保留对Clients的导航属性即可 public class Phones { public virtual int ID { get; set; } public virtual string Number { get; set; } public virtual PhoneCategory.PCategory Category { get; set; } public virtual Clients Client { get; set; } }
第二步:修正Fluent NHibernate映射配置
ClientsMap修改
public class ClientsMap : ClassMap<Clients> { public ClientsMap() { Table("Client"); // 注意你的SQL表名是Client不是Clients,之前此处配置错误 Id(x => x.ID); Map(x => x.Name); Map(x => x.Email); Map(x => x.BirthDate); // 配置一对多关联 HasMany(x => x.Phones) .KeyColumn("ClientID") // 指定Phones表的外键字段 .Inverse() // 由Phones端维护关联关系,优化性能 .Cascade.AllDeleteOrphan(); // 级联操作,Client保存/删除时自动同步关联的Phone记录 } }
PhonesMap修改
public class PhonesMap : ClassMap<Phones> { public PhonesMap() { Table("Phones"); Id(x => x.ID); Map(x => x.Number); Map(x => x.Category).CustomType<PhoneCategory.PCategory>(); // 配置多对一关联,对应外键ClientID References(x => x.Client) .Column("ClientID") .Not.Nullable(); } }
第三步:视图整合逻辑
配置完成后可直接预加载关联的Phone集合,避免懒加载性能问题,示例查询代码:
// 查询所有客户及关联的电话记录 var clientsWithPhones = session.Query<Clients>() .Fetch(c => c.Phones) .ToList();
拿到查询结果后直接将Clients.Phones集合绑定到视图即可,新增/编辑场景下直接操作Clients.Phones集合内的对象,调用session.SaveOrUpdate(client)时会自动同步Phones表的数据,无需单独操作Phones表。
内容的提问来源于stack exchange,提问作者Victoralm
相关产品推荐
相关产品推荐

