使用反射.FirstOrDefault(谓语);如何调用IDBSet< T>?
给予IDbSet哪里人包含一个id属性,我怎么能一般执行以下命令:
given an IDbSet where Person contains an "Id" property, how can I execute the following command generically:
var p = PersonDbSet.FirstOrDefault(i=>i.Id = 3);
我可以建立谓词,并获得了FirstOrDefault扩展方法的引用,但我可以'不像是会放在一起:
I can build up the predicate, and get a reference to the FirstOrDefault extension method, but I can't seem to put it all together:
首先谓词
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);
现在的扩展方法的引用:
Now a reference to the extension method:
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 });
最后尝试执行方法:
Finally try to execute the method:
object retVal = genericMethod.Invoke(null, new object[] {dbSet, predicate});
抛出此消息一个ArgumentException:
throws an ArgumentException with this message:
型'System.Reflection.RuntimePropertyInfo'的对象不能转换为类型'System.Linq.IQuerable`1 [人]'。
"Object of type 'System.Reflection.RuntimePropertyInfo' cannot be converted to type 'System.Linq.IQuerable`1[Person]'."
有什么想法?
您必须使该方法的通用版本:
You have to make generic version of the method:
MethodInfo genericMethod = method.MakeGenericMethod(entityType);
object retVal = genericMethod.Invoke(dbSet, new object[] {expr});
BTW。你不应该试图获得 System.Linq.Queryable
的方法是什么? System.Linq.Enumerable
是所有关于LINQ的对象,看起来像你想打电话给你的数据库。
btw. shouldn't you try to get the method from System.Linq.Queryable
? System.Linq.Enumerable
is all about linq to objects and looks like you're trying to call your DB.