许多实体到一个联结表 NHibernate 建模
Posted
技术标签:
【中文标题】许多实体到一个联结表 NHibernate 建模【英文标题】:Many entities to one junction table NHibernate modelling 【发布时间】:2014-04-24 06:06:11 【问题描述】:我希望能够在我的 NHibernate 应用程序中的任何主要实体中添加一组 Notes。我可以看到您如何使用每个实体的单独连接表来做到这一点。但是,我希望能够避免这种情况,并且只有一个连接表 - 如果可能的话。
下面是到目前为止的代码,但是这将导致为每个实体加载所有注释,我只想为该特定实体加载注释。我需要采取哪些替代方法?
public class Entity
public virtual int Id get; set;
public class EntityType1 : Entity
public EntityType1()
Notes = new List<Note>();
public virtual string EntityTypeName get; set;
public virtual IList<Note> Notes get;set;
public class EntityType2 : Entity
public EntityType2()
Notes = new List<Note>();
public virtual string EntityType2Name get; set;
public virtual IList<Note> Notes get; set;
public class Note
public virtual int Id get; set;
public virtual IList<Entity> Entities get; set;
public virtual string NoteText get; set;
namespace FluentNHib.Mappings
public class EntityMap : ClassMap<Entity>
public EntityMap()
Id(m => m.Id);
public class EntityType1Map : ClassMap<EntityType1>
public EntityType1Map()
Id(m => m.Id);
Map(m => m.EntityTypeName1);
HasManyToMany(m => m.Notes).Table("EntityToNotes")
.ParentKeyColumn("EntityId")
.ChildKeyColumn("NoteId")
.LazyLoad()
.Cascade.SaveUpdate();
public class EntityType2Map : ClassMap<EntityType2>
public EntityType2Map()
Id(m => m.Id);
Map(m => m.EntityType2ame);
HasManyToMany(m => m.Notes).Table("EntityToNotes")
.ParentKeyColumn("EntityId")
.ChildKeyColumn("NoteId")
.LazyLoad()
.Cascade.SaveUpdate();
public class NoteMap : ClassMap<Note>
public NoteMap()
Id(m => m.Id);
Map(m => m.NoteText);
【问题讨论】:
【参考方案1】:我不确定真正的问题是什么:
...但是这将导致为每个实体加载所有注释,我只想为该特定实体加载注释...
是延迟加载的问题吗?或者实际上 Entity1 和 Entity2 可以具有相同的 ID,因此引用是混合的? (我希望这应该是下面答案的一部分)
无论如何,我想说我们可以实现您所需要的:将Note
映射到一张表EntityToNotes。这很好。
但是,总的来说,我不鼓励您使用many-to-many
。这只是我自己的感觉,经验。下面是一些有更多解释的链接:
解决方案草案:
所以,首先我们必须将表 "EntityToNotes" 扩展为两列
EntityToNoteId
列 - 我们需要新配对对象的主键
Discriminator
专栏
鉴别器列将用于(几乎像标准继承)
-
在创建过程中插入
Discriminator
值
过滤每个实体IList<Notes>
这些可能是配对实体(有一个抽象的基础收集常见的东西)
public abstract class EntityToNote<TEntity>
public abstract string Discriminator get; set;
public virtual TEntity Entity get;set;
public virtual Note Note get;set;
// the pairing objects
public class EntityType1ToNote : EntityToNote<EntityType1>
string _discriminator = "EntityType1"; // here we set the discriminator
public virtual string Discriminator
get return _discriminator;
set _discriminator = value;
...
// Similar for other pairing objects
实体现在将引用配对对象列表
public class EntityType1 : Entity
public virtual IList<EntityType1ToNote> Notes get;set;
...
public class EntityType2 : Entity
public virtual IList<EntityType2ToNote> Notes get; set;
...
这是映射的 sn-p(所有其他实体将具有通常的映射,包括 EntityType1ToNote
、EntityType2ToNote
...的 ClassMaps)
public class EntityType1Map : ClassMap<EntityType1>
public EntityType1Map()
Id(m => m.Id);
Map(m => m.EntityTypeName1);
HasMany(m => m.Notes)
// this "table" setting is redundant, it will come from EntityType1ToNote
//.Table("EntityToNotes")
.KeyColumn("EntityId")
// here is the trick, that only related rows will be selected
.Where("Discriminator = 'EntityType1'")
.Cascade.AllDeleteOrphan();
正如我试图在提供的链接中解释的那样,我们通过这种方式获得了很多。主要是能够在配对表上使用更多列 - 例如Discriminator
(以后我们可以有更多的列,例如 SortBy
...) 我们可以使用强大的子查询搜索 - 请参阅 Query on HasMany reference
另外,事实上,配对可以通过真正的继承来映射...... 但这里的重点是:我们引入了配对对象,而不是many-to-many
,并获得了一个很多
【讨论】:
以上是关于许多实体到一个联结表 NHibernate 建模的主要内容,如果未能解决你的问题,请参考以下文章