Unit Test method with EF.Functions.Contains()
Asked Answered
S

1

6

I have got a method which contains a call to EF.Functions.Contains. Now I want to write unit tests for this method with a InMemory database, but I am getting instantly the following exception System.InvalidOperationException : The 'Contains' method is not supported because the query has switched to client-evaluation.

My method looks like this

var attributeValues = Context.AssetAttributeValues
                                         .Include(a => a.AssetAttribute)
                                         .Include(a => a.Asset)
                                         .Where(i => EF.Functions.Contains(i.Value, searchString));

I know that this exception is thrown because I have got no fulltext index on my InMemory database compared to my productive SQL Server instance but how do I get the same index on the InMemory database?

Is there any way to get arround this exception?

Slalom answered 5/4, 2019 at 10:0 Comment(2)
One solution is use: .Where(i => i.Value.Contains(searchString));Pridemore
@Pridemore this is unfortunately no option, because this is a huge table so that I had to create a fulltext index. With your solution the sql would just make a LIKE '%searchstring%' operation which is definitly not fast...Slalom
D
0

Like you said, EF.Functions.Contains can not be used in an InMemory database.

A workaround is to use IsSqlServer() to check whether you are running against a SQL Server or InMemory provider.

if(Context.IsSqlServer())  
    return Context.AssetAttributeValues
                                         .Include(a => a.AssetAttribute)
                                         .Include(a => a.Asset)
                                         .Where(i => EF.Functions.Contains(i.Value, searchString));
else
    return Context.AssetAttributeValues
                                         .Include(a => a.AssetAttribute)
                                         .Include(a => a.Asset)
                                         .Where(i => i.Value.Contains(searchString));
Disentitle answered 30/8, 2019 at 10:39 Comment(2)
It's not a good idea to write code so that that code can pass a unit test. Because what is that test proving then?Diapause
@CodeCaster: I agree, this is not a solution, just a workaround to the problem posed in the question. In fact, by doing this you are shipping an untested if-block to production.Disentitle

© 2022 - 2024 — McMap. All rights reserved.