我想获取带有条件的数据作为 lambda 表达式,如 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);
.
.
}
当我查看测试对象 SQL 查询时,它使用其中的 where 子句。但是 test2 对象查询就像只 select * from table 一样。它从数据库获取所有数据,然后在代码端使用when方法。由于 test2 查询大数据需要很长时间,因此如何使用 where 子句获取数据。唯一的区别是具有泛型类的代码之一,但 sql 查询不同。谢谢。
您的情况属于
Func<T, bool>
类型。当您查看 context.Set<T>().Where()
的重载时,您可以看到,采用 Func<T, bool>
的那个返回 IEnumerable<T>
而不是 IQuerable<T>
,因为它从源中获取所有数据,然后 应用过滤器。您应该使用Expression<Func<T, bool>> condition
。你的方法应该是这样的:
public IQueryable<T> GetBy<T>(Expression<Func<T, bool>> condition)
where T : class
{
return Context.Set<T>().Where(condition);
}
注意: 如果您想在过滤后返回 IEnumerable,您可以保持如下:
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();
}
Expression
来代替。
Expression<Func<T, bool>> condition
当您使用
Func
时,它无法转换为SQL。您获得全部数据并在内存中过滤它们。 如果是
Expression
,它将转换为 SQL,您将从 SQL 服务器获得过滤后的数据。
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);
}
使用
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 == "");