question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Sql.Row doesn't work with server-side functions

See original GitHub issue

Sorry to bother, but this is not supported yet:

await Events.Where(x => x.Id == key)
            .Set(d => Sql.Row(d.Title, d.SearchVector),
                t => (from x in Events
                    where t.Id == x.Id
                    select Sql.Row(t.Title, EF
                        .Functions
                        .ToTsVector("test")
                    )).Single())
            .UpdateAsync();

model:

public class Event
{
    [LinqToDB.Mapping.PrimaryKey] public Guid Id { get; set; }
    public string Title { get; set; } = "";
    public NpgsqlTsVector? SearchVector { get; set; } = null;
}
System.InvalidOperationException: The 'ToTsVector' method is not supported because the query has switched to client-evaluation. This usually happens when the arguments to the method cannot be translated to server. Rewrite the query to avoid client evaluation of arguments so that method can be translated to server.
         at Microsoft.EntityFrameworkCore.NpgsqlFullTextSearchDbFunctionsExtensions.ToTsVector(DbFunctions _, String document)
         at lambda_method215(Closure , Expression , IDataContext , Object[] )
         at LinqToDB.Linq.QueryRunner.SetParameters(Query query, Expression expression, IDataContext parametersContext, Object[] parameters, Int32 queryNumber, SqlParameterValues parameterValues)
         at LinqToDB.Linq.QueryRunnerBase.SetCommand(Boolean forGetSqlText)
         at LinqToDB.Data.DataConnection.QueryRunner.ExecuteNonQueryAsync(CancellationToken cancellationToken)
         at LinqToDB.Linq.QueryRunner.NonQueryQueryAsync(Query query, IDataContext dataContext, Expression expression, Object[] ps, Object[] preambles, CancellationToken cancellationToken)
         at LinqToDB.Linq.QueryRunner.NonQueryQueryAsync(Query query, IDataContext dataContext, Expression expression, Object[] ps, Object[] preambles, CancellationToken cancellationToken)
         at LinqToDB.Linq.ExpressionQuery`1.LinqToDB.Async.IQueryProviderAsync.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
         at LinqToDB.LinqExtensions.UpdateAsync[T](IUpdatable`1 source, CancellationToken token)

_Originally posted by @sep2 in https://github.com/linq2db/linq2db/issues/3321#issuecomment-1092875003_

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
jods4commented, Apr 8, 2022

Just to spell it out clearly in case anyone else has similar issues:

Simple expressions can be evaluated anywhere, but some expressions can only be evaluated server-side (i.e. SQL) and some can only be evaluated client-side (i.e. .NET).

Sql.Row is an example of a server-side feature that linq2db can only translate to SQL and never evaluates in C#, esp. in the UPDATE case here.

When linq2db doesn’t know how to translate a complex function to SQL, such as ToTsVector here, it just evaluates it in .NET.

But obviously you can’t mix-and-match both worlds. Putting .net code inside SQL is not possible, so nesting ToTsVector inside Row can’t be executed by linq2db. As @MaceWindu pointed out the solution is to teach linq2db how to translate the client-side code into SQL, e.g. with a custom [Expression] function.

Happy to see people other than me having uses for Sql.Row just one day after release 😃

1reaction
MaceWinducommented, Apr 8, 2022

Simplest one is to use Sql.Expression:

[Sql.Expression("{0} || {1}", ServerSideOnly=true)]
public static NpgsqlTsVector TsVectorConcat(NpgsqlTsVector left, NpgsqlTsVector right) => throw new InvalidOperationException();
Read more comments on GitHub >

github_iconTop Results From Across the Web

php/sql query works locally but does not work on server
i am using the following update query to update my code. it works fine on local server but not working on live server,...
Read more >
Troubleshoot queries that seem to never end in SQL Server
Provides steps to help you identify and resolve issues where a query runs for a long time in SQL Server.
Read more >
Working with SQL Server ROWCOUNT
The rows affecting statement can be any INSERT, UPDATE, DELETE or SELECT statement that is executed directly before the @@ROWCOUNT execution, ...
Read more >
Overview of the SQL ROW_NUMBER function
The Row_Number function is applied with the order of the CustomerID column. The temporary value starts from 1 assigned based on the order...
Read more >
7 Things Developers Should Know About SQL Server
7. SQL functions rarely perform well. · 6. “WITH (NOLOCK)” doesn't actually mean no locking. · 5. Use 3 connection strings in your...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found