C# 多实体到一个连接表NHibernate建模
我希望能够向我的NHibernate应用程序中的任何主要实体添加注释集合。我可以看到如何使用每个实体的单独连接表来实现这一点。然而,我希望能够避免这种情况,并且只有一个连接表——如果可能的话 下面是到目前为止的代码,但是这将导致为每个实体加载所有注释,我只想加载该特定实体的注释。我需要采取哪些替代方法C# 多实体到一个连接表NHibernate建模,c#,.net,nhibernate,fluent-nhibernate,C#,.net,Nhibernate,Fluent Nhibernate,我希望能够向我的NHibernate应用程序中的任何主要实体添加注释集合。我可以看到如何使用每个实体的单独连接表来实现这一点。然而,我希望能够避免这种情况,并且只有一个连接表——如果可能的话 下面是到目前为止的代码,但是这将导致为每个实体加载所有注释,我只想加载该特定实体的注释。我需要采取哪些替代方法 public class Entity { public virtual int Id { get; set; } } public class
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);
}
}
公共类实体
{
公共虚拟整数Id{get;set;}
}
公共类EntityType1:实体
{
公共实体类型1()
{
注释=新列表();
}
公共虚拟字符串EntityTypeName{get;set;}
公共虚拟IList注释{get;set;}
}
公共类EntityType2:实体
{
公共实体类型2()
{
注释=新列表();
}
公共虚拟字符串EntityType2Name{get;set;}
公共虚拟IList注释{get;set;}
}
公开课堂讲稿
{
公共虚拟整数Id{get;set;}
公共虚拟IList实体{get;set;}
公共虚拟字符串NoteText{get;set;}
}
}
命名空间FluentNHib.Mappings
{
公共类EntityMap:ClassMap
{
公共实体映射()
{
Id(m=>m.Id);
}
}
公共类EntityType1Map:ClassMap
{
公共实体类型1Map()
{
Id(m=>m.Id);
映射(m=>m.EntityTypeName1);
HasManyToMany(m=>m.Notes).表(“EntityToNotes”)
.ParentKeyColumn(“EntityId”)
.ChildKeyColumn(“NoteId”)
.LazyLoad()
.Cascade.SaveUpdate();
}
}
公共类EntityType2Map:ClassMap
{
公共实体类型2Map()
{
Id(m=>m.Id);
映射(m=>m.EntityType2ame);
HasManyToMany(m=>m.Notes).表(“EntityToNotes”)
.ParentKeyColumn(“EntityId”)
.ChildKeyColumn(“NoteId”)
.LazyLoad()
.Cascade.SaveUpdate();
}
}
公共类NoteMap:ClassMap
{
公共NoteMap()
{
Id(m=>m.Id);
Map(m=>m.NoteText);
}
}
我不确定真正的问题是什么:
…但是,这将导致为每个实体加载所有注释,我只想加载该特定实体的注释
是延迟加载的问题?还是事实上Entity1和Entity2可以有相同的ID,因此引用是混合的?(我希望这是下面答案的一部分)
无论如何,我想说我们可以实现您所需要的:只需一个表映射注释,这很好
但是,总的来说,我会劝阻您不要使用多对多
。这只是我自己的感觉、经验。下面是一些有更多解释的链接:
解决方案草案:
因此,首先我们必须用两列扩展表“EntityToNotes”
EntityToNoteId
列-我们需要新配对对象的主键
鉴别器
列
鉴别器列将用于(几乎类似于标准继承)
在创建过程中插入鉴别器值
过滤每个实体的teIList
这些可能是配对实体(具有收集公共内容的抽象基础)
正如我试图在提供的链接中解释的那样,我们通过这种方式获得了很多好处。主要是能够在配对表中使用更多列,例如Discriminator
(稍后我们可以使用更多列,如SortBy
),并且我们能够使用强大的子查询搜索-请参阅
此外,事实上,配对可以通过真正的继承进行映射……但这里的要点是:而不是多对多
我们引入了配对对象并获得了很多
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; }
...
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();
}
}