我试图传递lambda表达式和类型到我的DAL。我有这样的语句:
(entities).GetType().GetMethod("Where")
"entities"是DataContext上的实体表。
当我运行的语句,我得到一个空,即使Linq。表继承了IQueryable.
有人知道吗?
下面是整个方法:
public object GetResultSet(Dictionary<Type, Func<object, bool>> values)
{
using (ICSDataContext db = DataContextFactory.CreateDataContext<ICSDataContext>(DataContexts.ICS))
{
foreach (var entry in values)
{
var property = db.GetType().GetProperty(entry.Key.Name + "s");
IQueryable entities = (IQueryable)property.GetValue(db, null);
var whereMethod = (entities).GetType().GetMethod("Where")
.MakeGenericMethod(Type.GetType(entry.Key.AssemblyQualifiedName));
return whereMethod.Invoke(entities, new object[] { entry.Value });
}
}
return null;
}
谢谢
你也可以这样做
db.Set<Type>()
,它将返回适当类型的DBSet, Where可访问而不反射。此外,您可能希望使用Expression>而不是Func,表达式适用于查询对象,而funcs适用于枚举对象。如果你把一个函数传递给Where子句,它会把整个dbset拉下来并在内存中处理它。
类型化表达式也更容易使用(智能,类型检查)。
Expression<Func<User,bool>> filter = c=>c.FirstName == "Bob";
作为另一种选择,您可以查看System.Linq。动态,ScottGu在这里写了一篇文章。这篇文章和代码都是旧的,但它适用于EF 6。它允许
.Where("CategoryId=2 and UnitPrice>3")
摘自LukeH的回答:
var where1 = typeof(Queryable).GetMethods()
.Where(x => x.Name == "Where")
.Select(x => new { M = x, P = x.GetParameters() })
.Where(x => x.P.Length == 2
&& x.P[0].ParameterType.IsGenericType
&& x.P[0].ParameterType.GetGenericTypeDefinition() == typeof(IQueryable<>)
&& x.P[1].ParameterType.IsGenericType
&& x.P[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>))
.Select(x => new { x.M, A = x.P[1].ParameterType.GetGenericArguments() })
.Where(x => x.A[0].IsGenericType
&& x.A[0].GetGenericTypeDefinition() == typeof(Func<,>))
.Select(x => new { x.M, A = x.A[0].GetGenericArguments() })
.Where(x => x.A[0].IsGenericParameter
&& x.A[1] == typeof(bool))
.Select(x => x.M)
.SingleOrDefault();
然后:
var gmi = where1.MakeGenericMethod(typeof(T));