SQL Server linq2db. fallback for provider specific function

shyt4zoc  于 2023-10-15  发布在  其他
关注(0)|答案(1)|浏览(105)

I'm using Linq-to-DB (linq2db, linq2db.EntityFrameworkCore).

My software supports several database providers (SQL Server, PostgreSQL). There is a case when I need to use a provider specific function for SQL Server, and for PostgreSQL use an alternative option, or ignore it.

For example, I need this code to work with two providers.

In the case of SQL Server, the ISJSON must be performed, and in the case of PostgreSQL, it must be ignored:

var d1 = db.Invoice
           .Where(i => SqlFn.IsJson(i.InvoiceState) == true)
           .ToLinqToDB().ToList();

Now in the case of PostgreSQL I get an error

'IsJson(i.InvoiceState)' cannot be converted to SQL

How to do this correctly?

gcuhipw9

gcuhipw91#

You can create other function which handles other providers:

public static class DbFunctions
{
    [ExpressionMethod(ProviderName.SqlServer, nameof(SqlServerIsJson))]
    [ExpressionMethod(nameof(EmptyIsJson))]
    [return: NotNullIfNotNull(nameof(expression))]
    public static bool? IsJson(string? expression)
    {
        throw new InvalidOperationException($"'{nameof(IsJson)}' is a server side only function.");
    }
    
    static Expression<Func<string?, bool?>> SqlServerIsJson()
        => e => SqlFn.IsJson(e);

    static Expression<Func<string?, bool?>> EmptyIsJson()
        => e => false;
}

And use in your queries:

var d1 = db.Invoice
           .Where(i => DbFunctions.IsJson(i.InvoiceState) == true)
           .ToLinqToDB().ToList();

相关问题