Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/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# 比较相同用户定义类型的两个列表_C#_Performance_Linq - Fatal编程技术网

C# 比较相同用户定义类型的两个列表

C# 比较相同用户定义类型的两个列表,c#,performance,linq,C#,Performance,Linq,我有一个这样的数据集 cpeid cveid LastEdited cpe:/o:microsoft:windows_8.1:- CVE-2015-0001 2017-01-28 17:03:21.197 cpe:/o:microsoft:windows_8:- CVE-2015-0001 2017-01-28 17:03:21.197 cpe:/o:microsoft:wind

我有一个这样的数据集

cpeid                                cveid             LastEdited
cpe:/o:microsoft:windows_8.1:-      CVE-2015-0001   2017-01-28 17:03:21.197
cpe:/o:microsoft:windows_8:-        CVE-2015-0001   2017-01-28 17:03:21.197
cpe:/o:microsoft:windows_rt:-:gold  CVE-2015-0001   2017-01-28 17:03:21.197
以及像这样的支持实体:

public partial class cve_cpe
{
    [StringLength(250)]
    public string cpeid { get; set; }

    [Key]
    [Column(Order = 0)]
    [StringLength(250)]
    public string cveid { get; set; }

    [Key]
    [Column(Order = 1, TypeName = "smalldatetime")]
    public DateTime LastEdited { get; set; }
}
我在一个简单的c#控制台应用程序的数据库上使用entityframework for basic crud。在代码的某个地方,我这样做:

var mappings_to_add =  distinct_mappings_from_file
                      .Except(all_mappings, new cve_cpeComparer())
                      .ToList();
我的
IEqualityComparer
实现是:

    class cve_cpeComparer : IEqualityComparer<cve_cpe>
    {
        public bool Equals(cve_cpe x, cve_cpe y)
        {
            if (object.ReferenceEquals(x, y))
                return true;
            if (x == null || y == null)
                return false;
            return x.cpeid == y.cpeid && x.cveid == y.cveid;
        }

        public int GetHashCode(cve_cpe obj)
        {
            return obj.cveid.GetHashCode() ^ obj.cpeid.GetHashCode();
        }
    }
class cve\u CPE比较器:IEqualityComparer
{
公共布尔等于(cve_cpe x,cve_cpe y)
{
if(object.ReferenceEquals(x,y))
返回true;
如果(x==null | | y==null)
返回false;
返回x.cpeid==y.cpeid&&x.cveid==y.cveid;
}
公共int GetHashCode(cve_cpe obj)
{
返回obj.cveid.GetHashCode()^obj.cpeid.GetHashCode();
}
}
但这并不简单。我尝试了各种关于实现GetHashCode的建议,在entity和db中设置适当的键,手动从db中删除重复项,但根本不起作用。我错过了什么

因此,基本上,我希望linq
。除了
之外,它会给我列表中那些在db中不存在的条目,即忽略那些在db数据列表中具有相同组合的
cveid
cpeid

非常有趣的是,这件事与许多其他我的用户定义类型一起工作,它们的风格是
IEqualityComparer
(逻辑上实现相同),所以想知道我做错了什么吗?是用这些符号串的值吗

更新

所以它现在可以工作了,事实证明,这是因为实体和modelbuilder中的pk配置错误,解决了这个问题。
但是现在我想知道为什么
LINQ。除了
甚至担心主键,特别是当我给它提供一个定制的
IEqualityComparer

我无意中进入了这个页面,
IEqualityComparer.GetHashCode
实现引起了我的注意。想象一下下面的代码:

var list = new List<cve_cpe>
{
    new cve_cpe { cpeid = "1", cveid = "2" },
    new cve_cpe { cpeid = "2", cveid = "1" }
};

var result = list.Except(list, new cve_cpeComparer()).ToList();

您是想在数据库中执行except(使用EF查询)还是在内存中已经物化的列表中执行?它正在内存中的
物化列表中执行。您的相等比较器将
{cpeid,cveid}
对视为定义唯一性。但是实体PK(唯一键)是
{cveid,LastEdited}
。显然其中一个是错误的,必须纠正。是的,就是这样,错误的pk配置。现在可以了。谢谢,但你能帮我理解一下,为什么它(linq to entity)还要为PK操心呢?当我在内存中处理分离列表时?我的意思是,在iQualityComparer中,我从不关心PKIt在您的独立列表中的工作。但问题是它对
映射到\u add
的假设是错误的,所以我想问题是当您真正尝试将它们添加到数据库中时,您会遇到唯一的约束冲突。甚至在将它们添加(附加)到上下文时,因为EF在内存中内部维护唯一的键索引。
public int GetHashCode(cve_cpe obj)
{
    return obj.cveid.GetHashCode() * 11 /*Any prime number*/ ^ obj.cpeid.GetHashCode();
}