Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raw sql with EF Core and in-memory db provider

One of my API routes uses a raw sql merge into command in order to do an atomic upsert operation, and in my automated tests I've got a TestServer instance that uses the in-memory db provider. It gives me an error, probably because the in-memory provider doesn't support running raw sql commands - is that true? If not, how do I get it to work?

Here's the Startup class for the tests:

// In memory DB for testing
services.AddDbContext<MyContext>(optionsBuilder => optionsBuilder.UseInMemoryDatabase("stuff"));
services.AddDbContext<MyStatusContext>(optionsBuilder => optionsBuilder.UseInMemoryDatabase("status"));
services.AddDbContext<MyUserRolesContext>(optionsBuilder => optionsBuilder.UseInMemoryDatabase("userroles"));

And the API code is as you'd expect:

var count = await context.Database.ExecuteSqlCommandAsync(@"merge into ...", default(CancellationToken), ...);
return count;

This code works fine in production against a real database, I just can't get it working with the in-memory provider in my tests. Is there any hope for me? What's the usual test strategy for custom sql scripts?

like image 304
gzak Avatar asked Sep 06 '17 18:09

gzak


People also ask

Which method is used to execute the raw SQL query to the database in EF core?

Entity Framework Core provides the DbSet. FromSql() method to execute raw SQL queries for the underlying database and get the results as entity objects.

Is EF core faster than EF6?

Entity Framework (EF) Core, Microsoft's object-to-database mapper library for . NET Framework, brings performance improvements for data updates in version 7, Microsoft claims. The performance of SaveChanges method in EF7 is up to 74% faster than in EF6, in some scenarios.

What is raw SQL query?

Raw SQL, sometimes also called native SQL, is the most basic, most low-level form of database interaction. You tell the database what to do in the language of the database. Most developers should know basics of SQL. This means how to CREATE tables and views, how to SELECT and JOIN data, how to UPDATE and DELETE data.


2 Answers

There is no hope for you, as the InMemory provider is a NoSQL non-relational provider. You should use SQL Server (for example localdb) for integration testing

like image 176
ErikEJ Avatar answered Sep 20 '22 15:09

ErikEJ


As you've discovered the in-memory provider can't do relational operations (a reasonable limitation).

I had similar problems and ended up putting together a library to extend the in-memory provider to support relational operations - EntityFrameworkCore.Testing. It'll do the ExecuteSqlCommand/ExecuteSqlCommandAsync mocking.

like image 27
rgvlee Avatar answered Sep 20 '22 15:09

rgvlee