WithPartitionKey and in-memory database
With EF Core 5, WithPartitionKey has been added that will make your queries executes faster on a Cosmos database. But it does not work with in in-memory database.
The problem
WithPartitionKey is a nice addition a think. But if you also using an in-memory database (very convenient when doing unit tests) it will not work. If you try you will get an exception with the error message:
The LINQ expression 'DbSet<Blog>().WithPartitionKey("x")' could not be translated.
Either rewrite the query in a form that can be translated, or switch to client evaluation
explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or
'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'
The solution
My solution is to create my own extension method, I call it OnPartion
. When
this is used it calls WithPartitionKey
if cosmos database provider is used.
If not, then it will be translated to a Where
statement. For me, this is
good enough. But there are some limitations:
- The extension needs to be configured so it knows which way to go. I do this
in the
DbContext
constructor. - You cannot use both a cosmos database and a in-memory database in the same application. Not a major issue, I think.
- You need to create an extension for every entity you are using. I am not happy with that. But it not a major work.
Here is the code included in an example:
Summary
This solution is a bit ugly I think but it does solve the problem. In the future, hopefully there will be no need to use WithPartionKey. Instead, the partition could automatically be detected in a where statement. Read more on issue 20350.