比较自定义列表中的对象并返回不匹配的对象C#

时间:2018-08-21 11:32:06

标签: c# linq c#-4.0

我有两个模型

public class NewrecordModel
{
    public string NewName { get; set; }
    public string NewFileName { get; set; }
    public string NewFileVersion { get; set; }
}

public class OldrecordModel
{
    public string OldName { get; set; }
    public string OldFileName { get; set; }
    public string OldFileVersion { get; set; }
}

我需要将属性NewNameOldNameNewFileVersionOldFileVersion进行比较,并在列表中返回与NewrecordModel的差值。

我尝试了以下方法,

var unMatchedRecord = NewrecordModel.Where(o => !OldrecordModel.Any(n => n.OldName == o.NewName) || !OldrecordModel.Any(n => n.OldFileVersion == o.NewFileVersion)); 

上面的一个正在列表中返回不匹配的NewrecordModel,并且工作正常,但是我需要比较OldFileVersion小于NewFileVersion并立即返回列表。在查询中使用OldFileVersion小于NewFileVersion时,它会将不相关的数据列为输出。

下面是我尝试比较的查询

var unMatchedVersion = NewrecordModel.Where(o => OldrecordModel.Any(n => n.OldFileVersion.ToInt() < o.NewFileVersion.ToInt()));

以上linq是否正确?如何比较linq中的数字并返回结果。

2 个答案:

答案 0 :(得分:0)

我为获取属性名称和值编写了此内容,然后进行了更改。希望对您有帮助。

public static class CompareObject
    {
        /// <summary>
        /// Compares the properties of two objects of the same type and returns if all properties are equal.
        /// </summary>
        /// <param name="objectA">The first object to compare.</param>
        /// <param name="objectB">The second object to compre.</param>
        /// <param name="ignoreList">A list of property names to ignore from the comparison.</param>
        /// <returns><c>true</c> if all property values are equal, otherwise <c>false</c>.</returns>
        public static Dictionary<string,object> AreObjectsEqual(object objectA, object objectB, params string[] ignoreList)
        {
            //bool result;
            var list = new Dictionary<string, object>();
            if (objectA != null && objectB != null)
            {
                Type objectType;

                objectType = objectA.GetType();

                //result = true; // assume by default they are equal

                foreach (PropertyInfo propertyInfo in objectType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && !ignoreList.Contains(p.Name)))
                {


                    // if it is a primative type, value type or implements IComparable, just directly try and compare the value
                    if (CanDirectlyCompare(propertyInfo.PropertyType))
                    {
                        object valueA;
                        object valueB;

                        valueA = propertyInfo.GetValue(objectA, null);
                        valueB = propertyInfo.GetValue(objectB, null);
                        if (!AreValuesEqual(valueA, valueB))
                        {
                            list.Add(propertyInfo.Name, valueA);
                            //Console.WriteLine("Mismatch with property '{0}.{1}' found.", objectType.FullName, propertyInfo.Name);
                            //result = false;
                        }
                    }
                }
            }
            //else
            //    result = object.Equals(objectA, objectB);

            return list;
        }

        /// <summary>
        /// Determines whether value instances of the specified type can be directly compared.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>
        ///     <c>true</c> if this value instances of the specified type can be directly compared; otherwise, <c>false</c>.
        /// </returns>
        private static bool CanDirectlyCompare(Type type)
        {
            return typeof(IComparable).IsAssignableFrom(type) || type.IsPrimitive || type.IsValueType;
        }

        /// <summary>
        /// Compares two values and returns if they are the same.
        /// </summary>
        /// <param name="valueA">The first value to compare.</param>
        /// <param name="valueB">The second value to compare.</param>
        /// <returns><c>true</c> if both values match, otherwise <c>false</c>.</returns>
        private static bool AreValuesEqual(object valueA, object valueB)
        {
            bool result;
            IComparable selfValueComparer;

            selfValueComparer = valueA as IComparable;

            if (valueA == null && valueB != null || valueA != null && valueB == null)
                result = false; // one of the values is null
            else if (selfValueComparer != null && selfValueComparer.CompareTo(valueB) != 0)
                result = false; // the comparison using IComparable failed
            else if (!object.Equals(valueA, valueB))
                result = false; // the comparison using Equals failed
            else
                result = true; // match

            return result;
        }

    }

并使用

var changedColumns = CompareObject.AreObjectsEqual(NewrecordModel, OldrecordModel);

答案 1 :(得分:0)

  

它可能是NewrecordModel集合中的一个对象,为此OldrecordModel集合中没有相同名称的对象,或者OldrecordModel集合中任何名称相同的对象都有一个较小的OldFileVersion

检查以下代码:

    var unMatchedVersion = 
        newrecordModel.Where(o => !oldrecordModel.Any(n => n.OldName == o.NewName) ||
        oldrecordModel.Any(n => n.OldName == o.NewName && 
        int.Parse(n.OldFileVersion) < int.Parse(o.NewFileVersion)));