如何使用reflection调用IDBSet .FirstOrDefault(谓词)?
给定一个IDbSet,其中Person包含“Id”属性,如何执行以下命令:
var p = PersonDbSet.FirstOrDefault(i=>i.Id = 3);
我可以构建谓词,并获得对FirstOrDefault扩展方法的引用,但我似乎无法将它们放在一起:
首先是谓词
ParameterExpression parameter = Expression.Parameter(entityType, "Id"); MemberExpression property = Expression.Property(parameter, 3); ConstantExpression rightSide = Expression.Constant(refId); BinaryExpression operation = Expression.Equal(property, rightSide); Type delegateType = typeof (Func).MakeGenericType(entityType, typeof (bool)); LambdaExpression predicate = Expression.Lambda(delegateType, operation, parameter);
现在引用扩展方法:
var method = typeof (System.Linq.Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public) .FirstOrDefault(m => m.Name == "FirstOrDefault" && m.GetParameters().Count() == 2); MethodInfo genericMethod = method.MakeGenericMethod(new[] { entityType });
最后尝试执行该方法:
object retVal = genericMethod.Invoke(null, new object[] {dbSet, predicate});
使用此消息抛出ArgumentException:
“类型’System.Reflection.RuntimePropertyInfo’的对象无法转换为’System.Linq.IQuerable`1 [Person]’类型。”
有什么想法吗?
您必须制作该方法的通用版本:
MethodInfo genericMethod = method.MakeGenericMethod(entityType); object retVal = genericMethod.Invoke(dbSet, new object[] {expr});
顺便说一句。 你不应该尝试从System.Linq.Queryable
获取方法吗? System.Linq.Enumerable
都是关于linq到对象的,看起来你正试图调用你的数据库。
我想出了问题..我正在反映我的数据上下文以获取dbset,并返回属性信息而不是属性的值。
上面的代码现在工作得很好..感谢所有人的帮助!