Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct usage of linq2db along ef core #406

Open
neistow opened this issue Jan 21, 2025 · 2 comments
Open

Correct usage of linq2db along ef core #406

neistow opened this issue Jan 21, 2025 · 2 comments

Comments

@neistow
Copy link

neistow commented Jan 21, 2025

I'm trying to adopt linq2db in a project because it supports pessimistic locking. What is the right way to use linq2db along with regular EfCore?

Right now code like this throws an exception:

var book = await dbContext.Books
    .AsSqlServer()
    .WithUpdLockInScope()
    .WithRowLockInScope()
    .FirstOrDefaultAsync(); // or .FirstOrDefaultAsyncEF()
Unhandled exception. System.InvalidOperationException: The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'. Only providers that implement 'IAsyncQueryProvider' can be used for Entity Framework asynchronous operations.
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.FirstOrDefaultAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)

Only the LinqToDB extension method versions seem to be working.

Is calling .ToLinqToDBTable better? It seems to change method names for locking.

var book = await dbContext.Books
    .ToLinqToDBTable()
    .AsSqlServer()
    .WithUpdLock()
    .WithRowLock()
    .FirstOrDefaultAsyncLinqToDB();
@sdanyliv
Copy link
Member

You have to use FirstOrDefaultAsyncLinqToDB(), otherwise EF calls it's own FirstOrDefaultAsync, which expects EF Core's query provider.

ToLinqToDBTable changes QueryProvider to linq2db, and you cannot use EF Core extensions after that.

@neistow
Copy link
Author

neistow commented Jan 21, 2025

ToLinqToDBTable changes QueryProvider to linq2db, and you cannot use EF Core extensions after that.

Does it mean that calling any .FirstOrDefaultAsyncLinqToDB(); or any LinqToDB method will set query provider to linq2db even if ToLinqToDBTable was not specified?


I noticed that this type of query yields an invalid sql. Only first With statement is added (whichever is first). While if .ToLinqToDBTable() is used everything works as expected.

var book = await dbContext.Books
    .AsSqlServer()
    .WithUpdLockInScope() // only WITH (UPDLOCK) will be present in generated query
    .WithRowLockInScope()
    .FirstOrDefaultAsyncLinqToDB();

Will it be best practice to always use ToLinqToDBTable before utilizing any lib-specific methods?

Last but not least, will the linq2db query provider affect EF core behavior and functionality: like entity change tracking, JSON columns support, owned/value types, optimistic concurrency support, etc? Are there any cases when switching to the linq2db query provider will break existing behavior?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants