Reputation:
I want to get data with a condition as lambda expression like in.
public IEnumerable<T> GetBy(Func<T, bool> condition)
{
var test = Context.Set<StateInfo>().Where(p => p.CustomerID != null && p.CustomerID == 5);
var test2= Context.Set<T>().Where(condition);
.
.
}
When I am looking the test object SQL query It use where clause in It. But the test2 object query is like only select * from table. It gets all data from DB then use when method in code side. How can I get data with where clause because test2 query takes a long time with big datas. Only difference is one of the codes with generic class but the sql queries different. Thanks.
Upvotes: 4
Views: 2468
Reputation: 101
The question was asked a long time ago, but it was relevant to me now and in search of a solution I did it
public class Command<T> : IRepository<T>
{
public Context Context;
private IQueryable<T>? Reflection()
{
MethodInfo method = typeof(DbContext).GetMethod("Set", new Type[] { });
MethodInfo generic = method.MakeGenericMethod(typeof(T));
IQueryable<T>? queryable = ((IQueryable<T>)generic.Invoke(Context, null));
return queryable;
}
public IEnumerable<T> Where(Func<T, bool> Expression) => Reflection()?.Where(Expression);
public bool Any(Func<T, bool> Expression) => Reflection().Any(Expression);
public T? FirstOrDefault(Func<T, bool> Expression) => Reflection().FirstOrDefault(Expression);
}
Use
Command<People> people = new Command<People>();
var ss = people.Any(x => x.CompletedTasks == 1);
var re = people.Where(x => x.Name == x.Name).ToList();
Command<Product> product = new Command<Product>();
var res = product.Where(x => x.Name == x.Name).ToList();
var ssss = product.Any(x => x.Description == "");
Upvotes: 0
Reputation: 8696
Your condition is type of Func<T, bool>
. When you look at overload of context.Set<T>().Where()
you can see that, the one which takes Func<T, bool>
returns IEnumerable<T>
instaead of IQuerable<T>
, because it takes all the data from the source, then applies filter. You should use Expression<Func<T, bool>> condition
. Your method should be something like:
public IQueryable<T> GetBy<T>(Expression<Func<T, bool>> condition)
where T : class
{
return Context.Set<T>().Where(condition);
}
Note: If you want to return IEnumerable after filtering you can just keep it like:
public IEnumerable<T> GetBy<T>(Expression<Func<T, bool>> condition)
where T : class
{
// Should also work without AsEnumerable()
return Context.Set<T>().Where(condition).AsEnumerable();
}
Upvotes: 4
Reputation: 33381
Use Expression
instead.
Expression<Func<T, bool>> condition
When you use Func
it cant be trunslated to SQL. You get the whole data the filter them inmemory.
In case of Expression
it will transleared to SQL and you will get filtered data from SQL server.
Upvotes: 1