Pomelo.entityframeworkcore.mysql: string.Remove not work.

Created on 31 Dec 2020  路  2Comments  路  Source: PomeloFoundation/Pomelo.EntityFrameworkCore.MySql

I saw the https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/clr-method-to-canonical-function-mapping said that Remove can be translate. But it not work on this library.

DbContext.Set<Entity>().Where(entity => entity.StringProp.Remove(2) == "ab");

Got

InvalidOperationException: The LINQ expression 'DbSet<Entity>
    .Where(entity => entity.StringProp.Remove(2) == "ab")' 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 either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

version: the last

type-enhancement type-question

Most helpful comment

I saw the https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/clr-method-to-canonical-function-mapping said that Remove can be translate.

That is an old article about Entity Framework 6, not Entity Framework Core. When you open the article CLR Method to Canonical Function Mapping and then navigate to the grandparent article ADO.NET Entity Framework, there is no navigation back to the original article you linked. Instead, it only displays the following:

The docs.microsoft.com/ef/ site is now the main location for the Entity Framework content.

The content for this topic is now available on the following page: [Introducing Entity Framework}(https://docs.microsoft.com/en-us/ef/ef6/get-started).

EF Core introduced a provider specific function mapping page for each Microsoft provider in their docs for EF Core 5 (e.g. Function Mappings of the Microsoft SQL Server Provider).
As you can see, the String.Remove() method is not even being translated by SQL Server in EF Core (and also not by SQLite) and Pomelo does not currently translate it as well.

However, in the original article you referenced, there is the EF6 translation being mentioned, which should be easy to accomplish with the string methods/functions that are supported by Pomelo:

System.String method (instance) | Canonical function | Notes
--- | --- | ---
System.String Remove(Int32 startIndex) | Substring(this, 1, startIndex) |
System.String Remove(Int32 startIndex, Int32 count) | Concat(Substring(this, 1, startIndex) , Substring(this, startIndex + count +1, Length(this) - (startIndex + count))) | Remove(startIndex, count) is only supported if count is an integer greater than or equal to 0.

If you look at the .NET 5 source code for String.Remove(int startIndex), you get the following code, which also uses Substring() in the same way that the EF6 translation does:

```c#
// a remove that just takes a startindex.
public string Remove(int startIndex)
{
if (startIndex < 0)
throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);

if (startIndex >= Length)
    throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndexLessThanLength);

return Substring(0, startIndex);

}


Therefore, for the `String.Remove(Int32 startIndex)` method translation, which is the one you are interested in in your OP, you can just use the following call as a substitude:

```c#
context.MyEntities.Where(e => e.StringProp.Substring(0, 2) == "ab");

All 2 comments

I saw the https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/clr-method-to-canonical-function-mapping said that Remove can be translate.

That is an old article about Entity Framework 6, not Entity Framework Core. When you open the article CLR Method to Canonical Function Mapping and then navigate to the grandparent article ADO.NET Entity Framework, there is no navigation back to the original article you linked. Instead, it only displays the following:

The docs.microsoft.com/ef/ site is now the main location for the Entity Framework content.

The content for this topic is now available on the following page: [Introducing Entity Framework}(https://docs.microsoft.com/en-us/ef/ef6/get-started).

EF Core introduced a provider specific function mapping page for each Microsoft provider in their docs for EF Core 5 (e.g. Function Mappings of the Microsoft SQL Server Provider).
As you can see, the String.Remove() method is not even being translated by SQL Server in EF Core (and also not by SQLite) and Pomelo does not currently translate it as well.

However, in the original article you referenced, there is the EF6 translation being mentioned, which should be easy to accomplish with the string methods/functions that are supported by Pomelo:

System.String method (instance) | Canonical function | Notes
--- | --- | ---
System.String Remove(Int32 startIndex) | Substring(this, 1, startIndex) |
System.String Remove(Int32 startIndex, Int32 count) | Concat(Substring(this, 1, startIndex) , Substring(this, startIndex + count +1, Length(this) - (startIndex + count))) | Remove(startIndex, count) is only supported if count is an integer greater than or equal to 0.

If you look at the .NET 5 source code for String.Remove(int startIndex), you get the following code, which also uses Substring() in the same way that the EF6 translation does:

```c#
// a remove that just takes a startindex.
public string Remove(int startIndex)
{
if (startIndex < 0)
throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);

if (startIndex >= Length)
    throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndexLessThanLength);

return Substring(0, startIndex);

}


Therefore, for the `String.Remove(Int32 startIndex)` method translation, which is the one you are interested in in your OP, you can just use the following call as a substitude:

```c#
context.MyEntities.Where(e => e.StringProp.Substring(0, 2) == "ab");

@Flithor We did add official support for String.Remove() with #1284.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lauxjpn picture lauxjpn  路  3Comments

lebartha picture lebartha  路  3Comments

Toemsel picture Toemsel  路  3Comments

aramirezh-dev picture aramirezh-dev  路  3Comments

hainguyenthanh picture hainguyenthanh  路  3Comments