-
Notifications
You must be signed in to change notification settings - Fork 21
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
Issue with NeinLinq.EntityFramework, Linq.Count() method #39
Comments
That's weird, since the resulting query expressions look almost the same... List query:
Count query:
The processing of these expressions is completely different between Entity Framework and Entity Framework Core. Happily the newer Framework understands this anyway. Nevertheless, NeinLinq does some "clean-up" of the query's expression, which does handle properties but not method calls at the moment. Thus, this should work for you already: public class GetTodoItemsQueryProvider : IQueryProvider<ApplicationDbContext, int, TodoItem>
{
[InjectLambda(nameof(GetQueryExpression))]
public IQueryable<TodoItem> GetQuery(ApplicationDbContext context, int query)
{
throw new NotImplementedException();
}
public Expression<Func<ApplicationDbContext, int, IQueryable<TodoItem>>> GetQueryExpression()
{
return (context, query) => from todoItem in context.TodoItems
where todoItem.ListId == query
select todoItem;
}
} I can dig a little deeper to make Just for further reference, the test code I used in order to reproduce this: using System.Data.Entity;
using Xunit;
namespace NeinLinq.Tests;
public class SomeTest
{
private readonly ApplicationDbContext _dbContext;
private readonly IQueryProvider<ApplicationDbContext, int, TodoItem> _queryProvider;
public SomeTest()
{
_dbContext = new ApplicationDbContext("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SomeTest;Integrated Security=true;");
_dbContext.TodoLists.Add(
new TodoList
{
Items =
{
new TodoItem()
}
}
);
_dbContext.SaveChanges();
_queryProvider = new GetTodoItemsQueryProvider();
}
[Fact]
public void Test_WithLambdaInjection()
{
var query = from list in _dbContext.Set<TodoList>().ToDbInjectable()
let item = _queryProvider.GetQuery(_dbContext, list.Id).FirstOrDefault()
select item;
var result = query.ToList();
Assert.NotEmpty(result);
int count = query.Count();
Assert.NotEqual(0, count);
}
[Fact]
public void Test_WithoutLambdaInjection()
{
var query = from list in _dbContext.Set<TodoList>()
let item = (from todoItem in _dbContext.Set<TodoItem>()
where todoItem.ListId == list.Id
select todoItem).FirstOrDefault()
select item;
var result = query.ToList();
Assert.NotEmpty(result);
int count = query.Count();
Assert.NotEqual(0, count);
}
}
public class TodoList
{
public int Id { get; set; }
public virtual ICollection<TodoItem> Items { get; } = new List<TodoItem>();
}
public class TodoItem
{
public int Id { get; set; }
public int ListId { get; set; }
public virtual TodoList? List { get; set; }
}
public class ApplicationDbContext : DbContext
{
public DbSet<TodoList> TodoLists { get; }
public DbSet<TodoItem> TodoItems { get; }
public ApplicationDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
{
TodoLists = Set<TodoList>();
TodoItems = Set<TodoItem>();
}
}
public interface IQueryProvider<DbContext, TParam, TResult>
{
[InjectLambda]
IQueryable<TResult> GetQuery(DbContext context, TParam query);
}
public class GetTodoItemsQueryProvider : IQueryProvider<ApplicationDbContext, int, TodoItem>
{
[InjectLambda(nameof(GetQueryExpression))]
public IQueryable<TodoItem> GetQuery(ApplicationDbContext context, int query)
{
throw new NotImplementedException();
}
public Expression<Func<ApplicationDbContext, int, IQueryable<TodoItem>>> GetQueryExpression()
{
return (context, query) => from todoItem in context.TodoItems
where todoItem.ListId == query
select todoItem;
}
} |
Thanks for your research. |
Okay, after some further digging, it seems, that Entity Framework needs some processing, in order to understand, what you are doing here. This is currently implemented by an internal EF class I'm not quite happy with this "Hack", but please try Version 6.2.0 as it will be available as a Preview here: For implementation details: 66817a2 |
For some reason, I can't see this prerelease on NuGet and can't install it via command |
It isn't on NuGet, the previews are on GitHub only. See Installing a package for details |
Thank you. I checked, for my cases the problem is fixed |
Hi, I have a problem with the Count method in NeinLinq.EntityFramework
Framework: net4.8
EntityFramework: 6.4.4
NeinLinq: 6.1.1
NeinLinq.EntityFramework: 6.1.1
The code looks like this:
I have a query provider:
and code which query database and calls this query provider
the first request(with ToList) works without any problems
on second request I got an exception
Same code on NeinLinq.EntityFrameworkCore works fine, pls help
The text was updated successfully, but these errors were encountered: