使用NHibernate中的Parent -Child关系处理集合

ctb*_*ctb 1 collections nhibernate

当我处理两个列表(一个是旧的孩子(来自db),另一个列表带有修改后的孩子(来自用户输入)时,我遇到了一个问题,即找出要添加,更新和删除的子项.

目前,我必须遍历列表并进行比较以找出差异.

有没有人知道更好的方法,而不必循环列表?

Jam*_*Ide 6

IEnumerable.Except扩展方法是为这个完美的.在大多数情况下IEqualityComparer<T>,除非您在对象中仔细重写了Equals和GetHashCode,否则您将希望使用接受按身份进行比较的重载.

特定

IEnumerable<Company> oldList, IEnumerable<Company> newList
Run Code Online (Sandbox Code Playgroud)

代码是:

var companiesToAdd = newList.Except(oldList).ToArray();
var companiesToRemove = oldList.Except(newList).ToArray();
Run Code Online (Sandbox Code Playgroud)

ToArray()呼叫在那里,这样就可以更改原始列表而迭代添加和删除列表.

编辑:以下是两个实用程序类,使此操作变得简单.用法是

var diff = new DiffIEnumerable<Company>(oldList, newList, x => x.CompanyId);
var companiesToAdd = diff.InYNotX;
var companiesToRemove = diff.InXNotY;
Run Code Online (Sandbox Code Playgroud)
public class IdentityComparer<T> : IEqualityComparer<T> where T : class
{
    private readonly Func<T, object> _getIdentity;

    public IdentityComparer(Func<T, object> getIdentity)
    {
        _getIdentity = getIdentity;
    }

    public bool Equals(T x, T y)
    {
        if (x == null || y == null)
        {
            return false;
        }
        return _getIdentity(x).Equals(_getIdentity(y));
    }

    public int GetHashCode(T obj)
    {
        return _getIdentity(obj).GetHashCode();
    }
}
Run Code Online (Sandbox Code Playgroud)
public class DiffIEnumerable<T> where T : class
{
    public DiffIEnumerable(IEnumerable<T> x, IEnumerable<T> y, Func<T, object> getIdentity) :
        this(x, y, new IdentityComparer<T>(getIdentity))
    { }

    public DiffIEnumerable(IEnumerable<T> x, IEnumerable<T> y, IEqualityComparer<T> comparer)
    {
        InXAndY = x.Intersect(y, comparer).ToArray();
        InXNotY = x.Except(y, comparer).ToArray();
        InYNotX = y.Except(x, comparer).ToArray();
    }

    public IEnumerable<T> InXAndY { get; private set; }

    public IEnumerable<T> InXNotY { get; private set; }

    public IEnumerable<T> InYNotX { get; private set; }

}
Run Code Online (Sandbox Code Playgroud)