NHibernate Map by Code在一对多关系上复制列表项

时间:2016-04-10 15:17:02

标签: c# nhibernate orm

父类:

public class Group
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual byte[] Icon { get; set; }
    public virtual IList<Category> Categories { get; set; }
}

儿童班:

public class Category
{
    public virtual int Id { get; set; }
    public virtual string Description { get; set; }
    public virtual Group Group { get; set; }
}

映射:

public CategoryMapping()
{
    this.Table("[Category]");
    this.Schema("[RSS]");
    this.Id(x => x.Id, e => e.Generator(Generators.Identity));
    this.Property(x => x.Description, e =>e.NotNullable(true));
    this.ManyToOne(x => x.Group, e => e.Column("GroupId"));
}

public GroupMapping()
{
    this.Table("[Group]");
    this.Schema("[RSS]");
    this.Id(x => x.Id, e => e.Generator(Generators.Identity));
    this.Property(x => x.Name, e => e.NotNullable(true));
    this.Property(x => x.Icon, e => e.NotNullable(false));
    this.Bag(x => x.Categories, mapper => mapper.Key(e => e.Column("GroupId")), relation => relation.OneToMany());
    }

问题在于尝试获取组列表

var groupList = session.Query<Group>()
        .Fetch(x => x.Categories)
        .Take(10)
        .ToList();

上面的groupList最终会有重复的项目,比如

  1. 第1组
    • A类
    • B类
    • C类
  2. 第1组
    • A类
    • B类
    • C类
  3. 第1组
    • A类
    • B类
    • C类
  4. 列表应该是

    1. 第1组
      • A类
      • B类
      • C类
    2. 第2组
      • D类
      • E类
      • F类
    3. 代码中缺少什么?

      提前致谢。

1 个答案:

答案 0 :(得分:0)

您在上面的查询中遇到了笛卡尔产品问题。

选项1

我最近更改了我的映射,以通过将集合映射为集而不是包来避免这种情况。

此类更改需要您定义集合,如:

public virtual ISet<Category> Categories { get; set; }

你的映射会改为(这是猜测,因为我使用FNH而不是按代码映射):

this.Set(...)

如果您将映射更改为此,则必须覆盖实体的EqualsGetHashCode函数。我强烈建议使用基类来执行此操作,这样您就不必在每个实体中重复这些功能。这是这个基类的一个很好的起点:

https://github.com/nhibernate/NHibernate.AspNet.Identity/blob/master/source/NHibernate.AspNet.Identity/DomainModel/EntityWithTypedId.cs

选项2

您可以以不同方式查询项目,以避免使用本文所述的笛卡尔积:

Fighting cartesian product (x-join) when using NHibernate 3.0.0