0

We use entity framework to store our entities in the database. We use the repository pattern to wrap quite complicated Linq-queries. We want to unit test these queries against simple in memory collections. This is all fine and good until we ran into queries that order on the sql-type rowversion to find the last added record in a set. EntityFramework is capable to covert this Linq to SQL.

The row version is converted to a byte array by C# as it is too big to fit a ulong(?) when objects are rehydrated from the database.

So we add these byte arrays to our in memory test data. However if we run queries against our in memory set, the Linq explodes as an array of bytes is not comparable so it can not perform the needed sort.

So we wrote a comparer that works on byte arrays, when we use this comparer in our queries they work fine in memory.

But now LinqToEntities unable to handle the queries with the comparer.

We seem stuck in a catch 22…

Has anybody a solution that works in memory and in LinqToEntities?

k.c.
  • 1,755
  • 1
  • 29
  • 53
  • If you are wrapping an in memory collection with an IQueryable and using it to test logic that is going to run against a different IQueryable source like a DB your tests are no good and prove nothing because as you are finding out they behave differently. The same expression may not even be logically equivalent (especially if it involves nulls). – Mant101 Nov 01 '17 at 15:14
  • I agree it is not the same, but we take care that our left joins can handle the nulls. And yet, we still run a test set against a deployed DB. But doing that for all of our 4000 tests really bogs down the build-server. – k.c. Nov 03 '17 at 12:30

1 Answers1

0

This seems like a work around if you combine it with implementing Compare(this byte[]... as your comparer:

https://stackoverflow.com/a/19402565/2557128

NetMage
  • 26,163
  • 3
  • 34
  • 55
  • that solution does not work for an OrderBy or Max. We are goging to do the final filter in memory after the database has done the heavy lifting – k.c. Nov 01 '17 at 14:40
  • You couldn't do something like `OrderBy(rowversion.Compare())` ? – NetMage Nov 01 '17 at 18:28
  • That works for the in-memory queries, but can not be converted to SQL – k.c. Nov 03 '17 at 12:24
  • I think I see - you would actually need to use the `IComparer` version of `OrderBy` and that won't translate to SQL. I wonder if it is possible to change your entity to use a custom class that has a single property of type `byte[]` for the rowversion field and implements `IComparable` for in-memory, perhaps using `HasColumnType` or ComplexType? – NetMage Nov 03 '17 at 18:35
  • We have implemented the finnal in memmory sort solution. We do not have te freedom to alter the database, or even the DbContext. So this is the end of the line for us. Shame though that a usefull feature as the "version" which can even be used to identify the most recent row across diferent tables is not translated in a feature of EF – k.c. Nov 16 '17 at 12:32
  • EF lacks some SQL features, and EF Core is even much further behind, but hopefully it will be able to surpass EF some day. – NetMage Nov 16 '17 at 18:30