C# 在NHibernate中的一个保存操作中将实体列表添加到父实体

C# 在NHibernate中的一个保存操作中将实体列表添加到父实体,c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,我使用的是Fluent Nhibernate,我的相关实体包括: public class Product { public virtual int ID {get; set;} public virtual string Name {get; set;} public virtual Supplier Supplier {get; set;} } public class Supplier { public virtual int ID {get; set;}

我使用的是Fluent Nhibernate,我的相关实体包括:

public class Product
{
    public virtual int ID {get; set;}
    public virtual string Name {get; set;}
    public virtual Supplier Supplier {get; set;}
}

public class Supplier
{
    public virtual int ID {get; set;}
    public virtual string Name {get; set;}
    public virtual List<Product> Products {get; set;}
}
公共类产品
{
公共虚拟整数ID{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟供应商{get;set;}
}
公共类供应商
{
公共虚拟整数ID{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟列表产品{get;set;}
}
在映射中,供应商有许多关于产品+反向+级联的信息。所有这些信息都是为了一次保存所有产品切割。 我的产品主键和相等成员是用NH序列生成的Id

我需要创建一个新供应商的产品清单。如果我在产品从DB获得主键之前将其添加到列表中,那么只有第一个产品被添加到列表中,因为所有产品的ID都是0,因此equals方法返回true,并且列表“认为”它已经拥有该产品

我可以在添加到供应商列表之前逐个保存产品,以便获得数据库的Id值。但这并不使用级联能力


任何创造性的建议都将受到欢迎。

很明显,你是故意通过Id进行盲比较来打破平等

我通常在我的实体中执行not覆盖
Equals
,因为在某些不需要加载的情况下,它会强制加载

如果您确实想执行覆盖等于,可以执行以下操作:

public override bool Equals(object obj)
{
    if (Id == 0)
        return ReferenceEquals(this, obj);
    return obj != null && Id == ((Entity)obj).Id;
}

我不知道我是否100%理解了这个问题,但无论如何:

我们使用类似的方法,其中一个事件有一个注册列表。但是,正如您所提到的,我们会在保存实际事件之前先保存注册。当一次添加多个注册时,这会导致N+1问题,但在我们的场景中很少出现这种情况。如果我们使用另一个id生成器,比如HiLo,这个问题可能会消失?我不知道,因为我们还没有时间调查


当我们删除注册时,级联操作会成功运行,事件的注册集合也会正确更新。

为什么只有在相等时才依赖id?@wiero,因为它是我在DB中的主键。为什么?在这些情况下,你有什么建议?嗨,我做了一些研究,发现了这个问题,我认为这是一个好方法,对我来说,这并不明显,因为两个对象可以被视为相等,仅取决于数据库id,例如,同名产品和不同id的供应商将不同。这是一个有趣的问题:)+1谢谢,你的意思是什么:“它在一些不需要加载的情况下强制加载。”如果比较两个卸载的代理,默认情况下,NHibernate将根据Id执行此操作,而不必访问DB。如果覆盖相等,它将加载它们。NH为什么会这样做?如果不覆盖平等成员,你就要冒任何风险。在评论中解释这件事并不容易,但一旦你了解NH代理的工作原理,它就完全有意义了。不,如果您不在会话之间共享实体,那么不覆盖平等是没有风险的。请您客气一点,给我一篇在评论范围之外描述此行为的文章的参考资料好吗?=)我不知道为什么,但Hilo应该在进入真正的DB之前从会话中获取id,但这不适用于集合。