我试图将lambda表达式和类型传递给我的DAL。我有这样的声明:
(entities).GetType().GetMethod("Where")
"实体"是DataContext上的实体表。
当我运行语句时,即使Linq.Table继承了IQueryable,我也会得到null。
有人有想法吗?
以下是整个方法:
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;
}
由于
答案 0 :(得分:0)
作为替代方案,您可以执行类似
的操作db.Set<Type>()
将返回适当类型的DBSet,其中Where可以无反射。您也可以使用Expression&gt;而不是Func,表达式适用于可查询,其中funcs可用于枚举。如果将func传递给Where子句,它会将整个dbset拉下来并在内存中处理它。
键入的表达式也更容易使用(智能,类型检查)。
Expression<Func<User,bool>> filter = c=>c.FirstName == "Bob";
作为另一种选择,您可以查看System.Linq.Dynamic,ScottGu上有一篇文章here。文章和代码都很旧,但它适用于EF 6.它允许像
这样的东西.Where("CategoryId=2 and UnitPrice>3")
答案 1 :(得分:0)
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));