如何将保存为byte []的MD5哈希与Linq +实体框架进行比较?

时间:2014-08-26 14:20:01

标签: c# sql linq entity-framework

我必须在SQL Server 2005上的表中保存大量有关大量文件的信息。

我将每个文件的完整MD5存储为SQL上的varbinary,而.net数据库实体框架将其抽象为byte []数组。很公平。

我正在使用这样的查询查询所述表,比较哈希以检查文件是否已存在于db上:

byte[] hash = inputfile.GetFileMD5();
var query = context.CurveData
    .Where(n => n.MD5.Equals(hash))
    .Select(n => n.MD5)
    .DefaultIfEmpty(null).FirstOrDefault();

永远不应该将数组与.Equals()进行比较,因为它会比较实例,而不是序列。必须使用.SequenceEqual();但是,查询运行完全正常。如果我保存文件并对其运行查询,我确实从数据库中获取了正确的哈希值;很多其他文件也可以正常工作。

两个问题:

  1. 怎么可能?是否存在.Equals()的重载,它检查数组是否相等?
  2. 如何使用.SequenceEqual()实现上述查询?如果我尝试用.SequenceEqual()替换.Equals(),我会得到异常

      

    LINQ to Entities无法识别方法'Boolean SequenceEqual [Byte](System.Collections.Generic.IEnumerable 1[System.Byte], System.Collections.Generic.IEnumerable 1 [System.Byte])'

  3.      谢谢!

1 个答案:

答案 0 :(得分:3)

该查询中的代码不是作为C#代码运行的。它只是编译成Expression对象来描述代码是什么,而不是被翻译成最终可用于执行代码的IL代码。然后,查询提供程序可以查看这些Expression个对象,以查看您编写的内容,并对此信息执行任何操作。在这种特殊情况下,它最终将代码转换为SQL并执行数据库查询。该查询提供程序知道如何将这两个字节数组的Equals调用转换为正确的SQL来比较这两个数组。它的设计并不是为了理解SequenceEqual方法;它不知道如何将其转换为SQL,因此它只是错误。

无法使用SequenceEqual实施该查询。您可以尝试说服查询提供程序的作者支持它,或者您可以使用SequenceEqual然后尝试转换创建的Expression,以便所有SequenceEqual调用将成为{ {1}}电话,但这将是一项很多工作,而且我认为它没有任何效率。