多个实体到一个结点表NHibernate建模



我希望能够将Notes集合添加到我的NHibernate应用程序中的任何主要实体中。我可以看到你如何做到这一点,每个实体一个单独的连接表。然而,如果可能的话,我希望能够避免这种情况,并且只有一个接线表。

以下是到目前为止的代码,但这将导致为每个实体加载所有Notes,我只想加载该特定实体的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);
        }
    }

我不确定真正的问题是什么:

然而,这将导致为每个实体加载所有Notes,我只想加载该特定实体的Notes。。。

问题是懒惰加载吗?或者实际上Entity1和Entity2可以具有相同的ID,因此引用是混合的(我预计这应该是下面答案的一部分)

无论如何,我想说,我们可以实现您所需要的:只使用一个表映射NoteEntityToNotes。这很好。

但是,总的来说,我建议您不要使用many-to-many。这只是我自己的感受和经验。以下是一些有更多解释的链接:

  • 在使用流利的nhibernate时,我是否做了很多对很多错误的操作
  • NHibernate如何将对照表映射到包
  • Nhibernate:如何用一对多关系表示多对多关系

解决方案草案:

因此,首先我们必须用两列扩展表"EntityToNotes"

  • EntityToNoteId列-我们需要新配对对象的主键
  • Discriminator

鉴别器列将用于(几乎像标准继承)

  1. 在创建期间插入Discriminator
  2. 每个实体筛选te 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; }
    ...

以下是映射的片段(所有其他实体都将具有常规映射,包括EntityType1ToNoteEntityType2ToNote的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…),并且我们能够使用强大的子查询搜索-请参阅查询HasMany参考

此外,事实上,配对可以通过真正的继承映射但这里的要点是:我们引入了配对对象而不是many-to-many,并获得了很多

最新更新