Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 自定义IEqualityComparer,使用LINQ Except计算两个列表之间的差异_C#_Linq_Comparator - Fatal编程技术网

C# 自定义IEqualityComparer,使用LINQ Except计算两个列表之间的差异

C# 自定义IEqualityComparer,使用LINQ Except计算两个列表之间的差异,c#,linq,comparator,C#,Linq,Comparator,我用这个答案来找出使用Linq Except的两个列表之间的差异。但是,列表中的对象是泛型类型的,所以我为泛型类型编写了一个比较器,然后将其传递给Except方法。但是,我收到以下错误消息: 错误CS1929“List”不包含“Except”的定义,并且最佳扩展方法重载“ParallelEnumerable.ExceptParallelQuery,ParallelQuery,IEqualityComparer”需要“ParallelQuery”类型的接收器 我的电话: var differenc

我用这个答案来找出使用Linq Except的两个列表之间的差异。但是,列表中的对象是泛型类型的,所以我为泛型类型编写了一个比较器,然后将其传递给Except方法。但是,我收到以下错误消息:

错误CS1929“List”不包含“Except”的定义,并且最佳扩展方法重载“ParallelEnumerable.ExceptParallelQuery,ParallelQuery,IEqualityComparer”需要“ParallelQuery”类型的接收器

我的电话:

var differenceList = list1.Except(list2, new PropertyComparer<Guid>("ObjectId"));
我做错了什么?我怎样才能让它工作

更新

列表1和列表2类型:

EntityBase是


您应该将列表使用的相同类型传递给Except方法,在您的示例中,您使用的是Guid,但它应该是Contact类型,而且,您的Contact类没有名为ObjectId的属性,请尝试更改该属性。对于ContactId,以下操作似乎可以正常工作:

static void Main(string[] args)
{
     var list1 = new List<Contact>();
     list1.Add(new Contact() { ContactId = Guid.Parse("FB58F102-0CE4-4914-ABFF-ABBD3895D719") });
     list1.Add(new Contact() { ContactId = Guid.Parse("5A201238-6036-4385-B848-DEE598A3520C") });

     var list2 = new List<Contact>();
     list2.Add(new Contact() { ContactId = Guid.Parse("FB58F102-0CE4-4914-ABFF-ABBD3895D719") });

     var list3 = list1.Except(list2, new PropertyComparer<Contact>("ContactId"));

     foreach (var item in list3) 
         Console.WriteLine(item.ContactId.ToString());

     Console.ReadLine();
}

public class Contact
{
    public Guid ContactId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class PropertyComparer<T> : IEqualityComparer<T>
{
    private PropertyInfo _PropertyInfo;
    public PropertyComparer(string propertyName)
    {
        _PropertyInfo = typeof(T).GetProperty(propertyName,
            BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public);
        if (_PropertyInfo == null)
        {
            throw new ArgumentException(
                string.Format("{0} is not a property of type {1}.", propertyName, typeof(T)));
        }
    }

    public int GetHashCode(T obj)
    {
        object propertyValue = _PropertyInfo.GetValue(obj, null);
        if (obj == null) return 0;
        return propertyValue.GetHashCode();
    }

    public bool Equals(T x, T y)
    {
        object xValue = _PropertyInfo.GetValue(x, null);
        object yValue = _PropertyInfo.GetValue(y, null);

        if (xValue == null)
        {
            return yValue == null;
        }

        return xValue.Equals(yValue);
    }
}

您应该将列表使用的相同类型传递给Except方法,在您的示例中,您使用的是Guid,但它应该是Contact类型,而且,您的Contact类没有名为ObjectId的属性,请尝试更改该属性。对于ContactId,以下操作似乎可以正常工作:

static void Main(string[] args)
{
     var list1 = new List<Contact>();
     list1.Add(new Contact() { ContactId = Guid.Parse("FB58F102-0CE4-4914-ABFF-ABBD3895D719") });
     list1.Add(new Contact() { ContactId = Guid.Parse("5A201238-6036-4385-B848-DEE598A3520C") });

     var list2 = new List<Contact>();
     list2.Add(new Contact() { ContactId = Guid.Parse("FB58F102-0CE4-4914-ABFF-ABBD3895D719") });

     var list3 = list1.Except(list2, new PropertyComparer<Contact>("ContactId"));

     foreach (var item in list3) 
         Console.WriteLine(item.ContactId.ToString());

     Console.ReadLine();
}

public class Contact
{
    public Guid ContactId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class PropertyComparer<T> : IEqualityComparer<T>
{
    private PropertyInfo _PropertyInfo;
    public PropertyComparer(string propertyName)
    {
        _PropertyInfo = typeof(T).GetProperty(propertyName,
            BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public);
        if (_PropertyInfo == null)
        {
            throw new ArgumentException(
                string.Format("{0} is not a property of type {1}.", propertyName, typeof(T)));
        }
    }

    public int GetHashCode(T obj)
    {
        object propertyValue = _PropertyInfo.GetValue(obj, null);
        if (obj == null) return 0;
        return propertyValue.GetHashCode();
    }

    public bool Equals(T x, T y)
    {
        object xValue = _PropertyInfo.GetValue(x, null);
        object yValue = _PropertyInfo.GetValue(y, null);

        if (xValue == null)
        {
            return yValue == null;
        }

        return xValue.Equals(yValue);
    }
}

您正在调用的集合已使用AsParallel转换为parallelEnumerable。是否可以更新该问题以包括list1和list2的类型?列表是否为parallelEnumerable的类型?我已使用列表的类型更新了该问题。我在代码中的任何地方都没有使用AsParallel来转换列表。是的,但请告诉我们您是如何初始化和填充列表的。您调用的集合已使用AsParallel转换为parallelEnumerable的集合除外。您可以更新问题以包括list1和list2的类型吗?列表是parallelEnumerable的类型吗?我已更新这个问题与我的列表类型有关。我没有在代码中的任何地方使用AsParallel来转换列表。是的,但请告诉我们您是如何初始化和填充列表的。主要问题是,新的PropertyComparerContactId应该采用一种联系人类型来匹配列表的类型参数。OP最初使用Guid作为类型参数,这是导致错误的原因。我现在知道我应该使用Contact而不是Guid作为类型参数,但是将其更改为Contact并不能解决问题。错误文本现在是错误CS1929'List'不包含'Except'的定义,并且最佳扩展方法重载'ParallelEnumerable.ExceptParallelQuery,ParallelQuery,IEqualityComparer'需要'ParallelQuery'@devNull类型的接收器,相同的错误,仅更新了类型。我应该为这个问题创建一个单独的问题吗?清理您的项目,删除bin文件夹并重建,另外,创建一个新的空控制台项目并从答案中复制粘贴代码。这似乎有效……我将接受这个答案,因为它解决了其中一个问题,稍后我将创建另一个问题,以寻求对当前错误的帮助。非常感谢。主要问题是新的PropertyComparerContactId应该采用一种联系人类型来匹配列表的类型参数。OP最初使用Guid作为类型参数,这是导致错误的原因。我现在知道我应该使用Contact而不是Guid作为类型参数,但是将其更改为Contact并不能解决问题。错误文本现在是错误CS1929'List'不包含'Except'的定义,并且最佳扩展方法重载'ParallelEnumerable.ExceptParallelQuery,ParallelQuery,IEqualityComparer'需要'ParallelQuery'@devNull类型的接收器,相同的错误,仅更新了类型。我应该为这个问题创建一个单独的问题吗?清理您的项目,删除bin文件夹并重建,另外,创建一个新的空控制台项目并从答案中复制粘贴代码。这似乎有效……我将接受这个答案,因为它解决了其中一个问题,稍后我将创建另一个问题,以寻求对当前错误的帮助。非常感谢。
List<Contact>
public class Contact : EntityBase
{
    public Guid ContactId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<Email> Emails {get; set;}
}
public class EntityBase : IEntity
{
    public IQueryable<T> GetDBEntities<T>(ApplicationDbContext db) where T : class
    {
        return db.Set<T>();
    }

    public List<T> GetLocalEntities<T>() where T : class
    {
        var localProperties = this.GetType().GetProperties();
        foreach (var localProperty in localProperties)
        {
            var localPropertyValue = localProperty.GetValue(this);
            if (localPropertyValue != null && localPropertyValue.IsGenericList() == true)
            {
                var localPropertyValueType = localPropertyValue.GetType(); // List<object>
                var localPropertyValueTypeDecoupled = localPropertyValueType.GetGenericArguments().Single(); // List<T>
                if (localPropertyValueTypeDecoupled == typeof(T))
                {
                    return (List<T>)localPropertyValue;
                }
            }
        }
        throw new Exception("Entity Types Validation Error");
    }

    public void ProcessEntityReference<T>(ApplicationDbContext db) where T : class
    {
        // T is Email
        var remoteList = this.GetDBEntities<T>(db).ToList();
        var updatedList = GetLocalEntities<T>();
        var toBeAdded = updatedList.Except(remoteList, new PropertyComparer<Guid>("ContactId"));
        var toBeDeleted = new List<object>();
        throw new NotImplementedException();
    }

    public void ProcessEntityReferences(ApplicationDbContext db)
    {
        this.ProcessEntityReference<Email>(db);
    }
}
static void Main(string[] args)
{
     var list1 = new List<Contact>();
     list1.Add(new Contact() { ContactId = Guid.Parse("FB58F102-0CE4-4914-ABFF-ABBD3895D719") });
     list1.Add(new Contact() { ContactId = Guid.Parse("5A201238-6036-4385-B848-DEE598A3520C") });

     var list2 = new List<Contact>();
     list2.Add(new Contact() { ContactId = Guid.Parse("FB58F102-0CE4-4914-ABFF-ABBD3895D719") });

     var list3 = list1.Except(list2, new PropertyComparer<Contact>("ContactId"));

     foreach (var item in list3) 
         Console.WriteLine(item.ContactId.ToString());

     Console.ReadLine();
}

public class Contact
{
    public Guid ContactId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class PropertyComparer<T> : IEqualityComparer<T>
{
    private PropertyInfo _PropertyInfo;
    public PropertyComparer(string propertyName)
    {
        _PropertyInfo = typeof(T).GetProperty(propertyName,
            BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public);
        if (_PropertyInfo == null)
        {
            throw new ArgumentException(
                string.Format("{0} is not a property of type {1}.", propertyName, typeof(T)));
        }
    }

    public int GetHashCode(T obj)
    {
        object propertyValue = _PropertyInfo.GetValue(obj, null);
        if (obj == null) return 0;
        return propertyValue.GetHashCode();
    }

    public bool Equals(T x, T y)
    {
        object xValue = _PropertyInfo.GetValue(x, null);
        object yValue = _PropertyInfo.GetValue(y, null);

        if (xValue == null)
        {
            return yValue == null;
        }

        return xValue.Equals(yValue);
    }
}
5a201238-6036-4385-b848-dee598a3520c