Работа с коллекциями с отношениями Родитель-Ребенок в NHibernate - PullRequest
1 голос
/ 14 июля 2010

У меня проблема с выяснением, какие дочерние элементы добавить, обновить и удалить, когда я имею дело с двумя списками: один со старыми детьми (из БД), а другой - с измененными детьми (из пользовательского ввода) ,

В настоящее время я должен пройтись по спискам и сравнить, чтобы найти разницу.

Кто-нибудь знает лучший способ сделать это без циклического перебора списков?

1 Ответ

6 голосов
/ 14 июля 2010

Метод расширения IEnumerable.Except идеально подходит для этого.В большинстве случаев вы захотите использовать перегрузку, которая принимает IEqualityComparer<T> для сравнения по тождеству, если только вы тщательно не переопределили Equals и GetHashCode в ваших объектах.код:

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

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...