PomeloFoundation / Pomelo.EntityFrameworkCore.MySql

Entity Framework Core provider for MySQL and MariaDB built on top of MySqlConnector
MIT License
2.69k stars 383 forks source link

FromSql to FromSqlRaw - migrate 2.2.6 to 3.1.1 - netcore-3.1 #1031

Open virtualdreams opened 4 years ago

virtualdreams commented 4 years ago

Steps to reproduce

Upgrade package from 2.2.6 to 3.1.1 results in an error.

The issue

Before i change from FromSql to FromSqlRaw:

'RelationalQueryableExtensions.FromSql<TEntity>(IQueryable<TEntity>, FormattableString)' is obsolete: 'For returning objects from SQL queries using plain strings, use FromSqlRaw instead. For returning objects from SQL queries using interpolated string syntax to create parameters, use FromSqlInterpolated instead. Call either new method directly on the DbSet at the root of the query.' 

After i change from FromSql to FromSqlRaw:

'IQueryable<Note>' does not contain a definition for 'FromSqlRaw' and no accessible extension method 'FromSqlRaw' accepting a first argument of type 'IQueryable<Note>' could be found (are you missing a using directive or an assembly reference?)

Source sample:

var _query = Context.Note.AsQueryable();
_query = _query.FromSqlRaw($@"
select * from anywhere
");

Question

How to fix this issue and where is migration path or documentation about?

Further technical details

Operating system: Arch Linux Pomelo.EntityFrameworkCore.MySql version: 3.1.1 Microsoft.AspNetCore.App version: 3.1.2 (official from MS)

lauxjpn commented 4 years ago

[...] where is migration path or documentation about?

You can find everything about Raw SQL Queries in the EF Core docs.

How to fix this issue [...]

As the warning says, you need to

Call either new method directly on the DbSet at the root of the query.`

So for your example, the following should work:

var _query = Context.Note.FromSqlRaw($@"select * from anywhere");

The docs about the FromSqlRaw method state correctly, that the first parameter is of type DbSet<TEntity>:

this DbSet<TEntity> source

Therefore, you need to call this extension method on a DbSet<TEntity> object. It seems though, that the description of the parameter is inaccurate, because it says:

An IQueryable<T> to use as the base of the raw SQL query (typically a DbSet<TEntity>).

The same is stated for the FromSqlInterpolated method. This seems to be a copy & paste error in the docs, because the obsolete FromSql method was an extension method for IQueryable<TEntity> instead for DbSet<TEntity> and the description was probably just reused (/cc @ajcvickers).


Concrete upgrade documentation for FromSql can be found in the Raw SQL Queries article at the end.

General new and breaking changes can be found in the following (long) articles of the EF Core docs:

virtualdreams commented 4 years ago

Thanks. AsQueryable() was the problem here. Removing this causes some minor problems for me, but it works now with:

IQueryable<Note> _query = null;
// some other code
_query = Context.Note.FromSqlInterpolated($@"select * from anywhere where x = {value}");
// some other code
_query.ToListAsync();
lauxjpn commented 4 years ago

Let's keep this issue open until the docs for EF Core have been fixed.

lauxjpn commented 4 years ago

@ajcvickers Just a quick reminder to fix the EF Core docs.

lauxjpn commented 4 years ago

@ajcvickers I just wanted to correct this in the api reference docs myself, but I couldn't find them neither on the https://github.com/dotnet/dotnet-api-docs nor on the https://github.com/dotnet/EntityFramework.Docs repo.

Are the EF Core api reference docs hosted somewhere else?