在 NHibernate 中处理具有父子关系的集合

发布于 2024-09-10 05:18:05 字数 142 浏览 3 评论 0原文

当我处理两个列表时,我在找出要添加、更新和删除哪些子项时遇到问题,一个列表包含旧子项(来自数据库),另一个列表包含修改后的子项(来自用户输入)。

目前我必须循环遍历列表并进行比较以找出差异。

有谁知道更好的方法来做到这一点而不必循环列表?

I'm having a problem with finding out which children to add, update and delete when I'm dealing with two lists one with the old chidren (from db) and the other list with the modified children (from user input).

Currently I have to loop through the lists and compare to find the difference.

Does anyone know of a better way of doing this without having to loop through the lists?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ゝ偶尔ゞ 2024-09-17 05:18:05

IEnumerable.Except 扩展方法非常适合此目的。在大多数情况下,您需要使用接受 IEqualityComparer 的重载来按标识进行比较,除非您已在对象中仔细重写了 Equals 和 GetHashCode。

给定的

IEnumerable<Company> oldList, IEnumerable<Company> newList

代码是:

var companiesToAdd = newList.Except(oldList).ToArray();
var companiesToRemove = oldList.Except(newList).ToArray();

ToArray() 调用在那里,以便您可以在迭代添加和删除列表时对原始列表进行更改。

编辑:下面是两个实用程序类,可以使此操作变得容易。用法是

var diff = new DiffIEnumerable<Company>(oldList, newList, x => x.CompanyId);
var companiesToAdd = diff.InYNotX;
var companiesToRemove = diff.InXNotY;

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();
    }
}

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; }

}

The IEnumerable.Except extension method is perfect for this. In most cases you will want to use the overload that accepts an IEqualityComparer<T> to compare by identity, unless you have carefully overridden Equals and GetHashCode in your objects.

Given

IEnumerable<Company> oldList, IEnumerable<Company> newList

The code is:

var companiesToAdd = newList.Except(oldList).ToArray();
var companiesToRemove = oldList.Except(newList).ToArray();

The ToArray() calls are there so that you can make changes to the original list while iterating the add and remove lists.

Edit: Below are two utility classes that make this operation easy. Usage is

var diff = new DiffIEnumerable<Company>(oldList, newList, x => x.CompanyId);
var companiesToAdd = diff.InYNotX;
var companiesToRemove = diff.InXNotY;

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();
    }
}

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; }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文