简体   繁体   中英

How to compare MD5 hashes saved as byte[] with Linq + entity framework?

I have to save a bunch of information about a large amount files in a table on SQL server 2005.

I store the full MD5 of each file as a varbinary on SQL, and .net database entity framework abstracts it as a byte[]array. Fair enough.

I am querying against said table with a query like this, comparing hashes to check if a file already is on the db:

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

One should never compare Arrays with .Equals() because it compares instances, not sequences. .SequenceEqual() must be used; However, the query runs perfectly fine . If I save a file and run the query against it, I indeed get the correct hash from the database; lots of other files work fine too.

Two questions:

  1. How is that possible? Is there an overload of .Equals() that checks against array equality?
  2. How can I implement the above query with .SequenceEqual()? If I try to replace .Equals() with .SequenceEqual() I get the Exception

    LINQ to Entities does not recognize the method 'Boolean SequenceEqual[Byte](System.Collections.Generic.IEnumerable 1[System.Byte], System.Collections.Generic.IEnumerable 1[System.Byte])'

Thanks!

The code in that query is not run as C# code. It is merely compiled into Expression object that describe what the code was, instead of being translated into IL code that can eventually be used to execute the code. The query provider is then capable of looking at those Expression objects to see what you wrote, and doing...whatever with that information. In this particular case it ends up translating the code into SQL and executing a database query. That query provider knows how to translate the Equals call of these two byte arrays into the correct SQL to compare the two arrays. It wasn't designed to understand the SequenceEqual method; it doesn't know how to translate that into SQL, and so it just errors.

You cannot implement that query with SequenceEqual . You could try to convince the author of the query provider to support it, or you could use SequenceEqual and then try to transform the Expression that is created so that all SequenceEqual calls will become Equals calls, but that would be a lot of work and I don't see it being at all productive.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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