简体   繁体   English

比较相同类别的清单

[英]Compare Lists of same class

I have two lists I would like to compare them for updated/modified columns. 我有两个列表,我想比较它们的更新/修改列。 Compare 2 Lists of the same class and show the different values in a new list I would like to do this using linq. 比较相同类别的2个列表,并在新列表中显示不同的值,我想使用linq做到这一点。 The only problem is I am dealing with a lot of columns, over excess of 30 columns in each. 唯一的问题是我要处理很多列,每列超过30列。 Any suggestions would be of great help... 任何建议都会有很大帮助。

        //In Dal
        List<PartnerAndPartnerPositionEntity> GetAllPartnerAndPartnerPositionOldDB(int modelId);
        List<PartnerAndPartnerPositionEntity> GetAllPartnerAndPartnerPosition(int modelId);
        //BL
        //get from new db
        var list1= _partnerDAL.GetAllPartnerAndPartnerPosition(modelId);
        //get from old db
        var list2= _partnerDAL.GetAllPartnerAndPartnerPositionOldDB(modelId);

Let's assume that: 假设:

  1. PartnerAndPartnerPositionEntity class contains a property named Id that represents the unique key of an item PartnerAndPartnerPositionEntity类包含一个名为Id的属性,该属性表示项的唯一键

Given the above you can: 鉴于以上所述,您可以:

Get all properties of your type 获取您类型的所有属性

var properties = typeof(PartnerAndPartnerPositionEntity).GetProperties();

Join the two lists on the Id property and iterate through the properties to see which one has changed: 将两个列表加入Id属性,并遍历这些属性以查看哪个已更改:

var list = list1.Join(list2,
        x => x.Id,
        y => y.Id,
        (x, y) => Tuple.Create(x, y))
    .ToList();

list.Foreach(tuple =>
{
    foreach(var propertyInfo in properties)
    {
        var value1 = propertyInfo.GetValue(tuple.Item1, null);
        var value2 = propertyInfo.GetValue(tuple.Item2, null);
        if(value1 != value2)
            Console.WriteLine("Item with id {0} has different values for property {1}.",
                tuple.Item1,Id, propertyInfo.Name);
    }
});

Well, if you want to avoid doing it the boring and tedious way, you need to use reflection to dynamically get the class members then get their values for each instance. 好吧,如果您想避免这样做乏味而乏味,则需要使用反射来动态获取类成员,然后为每个实例获取其值。 See C# Reflection - Get field values from a simple class for the code. 有关代码,请参见C#反射-从简单的类获取字段值

There...this will generate new IL! 在那里...这将产生新的IL!

public static class EqualityHelper
{
    private ConcurrentDictionary<Type, object> _cache = new ConcurrentDictionary<Type, object>();
    public bool AreEqual<T>(T left, T right)
    {
        var equality = (Func<T,T,bool>)_cache.GetOrAdd(typeof(T), CreateEquality<T>());
        return equality(left, right);
    }

    private Func<T, T, bool> CreateEquality<T>()
    {
        var left = Expression.Parameter(typeof(T));
        var right = Expression.Parameter(typeof(T));
        var properties = from x in typeof(T).GetProperties()
                        where x.GetIndexParameters().Any() == false
                        select x;
        var expressions = from p in properties
                        select Expression.Equal(
                            Expression.Property(left, p),
                            Expression.Property(right, p));
        var body = expressions.Aggregate(Expression.AndAlso);
        var lambda = Expression.Lambda<Func<T,T,bool>>(body, new [] {left, right});
        return lambda.Compile();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM