动态、高效地调用DbSet上的add方法

本文关键字:上的 add 方法 DbSet 调用 高效 动态 | 更新日期: 2023-09-27 18:12:25

我想对DbSet上的Add方法进行动态调用,我在编译时不知道。

实际上,用简单的反射是可能的,但是性能很差。下面是我们现在使用的代码:

Type contextType = (context as Object).GetType();
var set = (contextType.GetProperty(entitySetName)).GetValue(context, null);
Type typeSet = set.GetType();
MethodInfo method = typeSet.GetMethod("Add");
Object[] args = { entity };
method.Invokke(set, args);

我已经尝试了另外两种不同错误的可能性。

第一个是使用委托
public delegate void MyDel<T>(T t,object entity);
Type contextType = (context as Object).GetType();
var set = (contextType.GetProperty(entitySetName)).GetValue(context, null);
Type typeSet = set.GetType();
MethodInfo method = typeSet.GetMethod("Add");
Type template = typeof(MyDel<>);
Type specific = template.MakeGenericType(childClassType);
Delegate test = Delegate.CreateDelegate(specific, method);

,但在最后一行,我得到以下错误:错误绑定到目标方法

第三个选项是像这样使用表达式树:

Type contextType = (context as Object).GetType();
var set = (contextType.GetProperty(entitySetName)).GetValue(context, null);
Type typeSet = set.GetType();
MethodInfo method = typeSet.GetMethod("Add");

ParameterExpression paramo = Expression.Parameter(typeSet, "param");
ParameterExpression parami = Expression.Parameter(typeSet, "newvalue");
Expression convertedParamo = Expression.Convert(paramo, typeof(Object));
Expression convertedParami = Expression.Convert(parami, typeof(Object));
MethodCallExpression methodCall = Expression.Call(convertedParamo, method, convertedParami);                    
Expression valueExp = Expression.Lambda(methodCall, paramo, parami);
Expression<Action<Object, Object>> dynamicExpression = (Expression<Action<Object, Object>>)valueExp;
Action<Object, Object> dynamicAction = dynamicExpression.Compile();
Object o = Activator.CreateInstance(otherType);
dynamicAction(o, entity);

但是在本例中,在"Expression "行。调用(convertedParamo,方法. .

i got this error:

DictionnaireONYX.Entites.ArticleSansFacturier方法"添加(DictionnaireONYX.Entites.ArticleSansFacturier)'声明类型"System.Data.Entity.DbSet"1 (DictionnaireONYX.Entites.ArticleSansFacturier)"不能用"System"类型的实例调用。对象'

其中ArticleSansFacturier是DbSet。

谁能帮我?

Thanks in advance

动态、高效地调用DbSet上的add方法

我不得不说我现在不知道性能如何,但在对代码进行一些更改后,它似乎可以工作。特别是最后的动态部分可能会出现一些问题。

我使用了一个包含Authors的ModelContext。

ModelContext context = new ModelContext();
Author entity = new Author();
string entitySetName = "Authors";
string methodName = "AddObject";
Type contextType = (context as Object).GetType();
var set = (contextType.GetProperty(entitySetName)).GetValue(context, null);
Type typeSet = set.GetType();
MethodInfo method = typeSet.GetMethod(methodName);
ParameterExpression paramo = Expression.Parameter(typeSet, "param");
ParameterExpression parami = Expression.Parameter(entity.GetType(), "newvalue");
MethodCallExpression methodCall = Expression.Call(paramo, method, parami);
Type typeofClassWithGenericStaticMethod = typeof(Expression);
MethodInfo methodInfo = typeofClassWithGenericStaticMethod.GetMethods().Where(m => m.Name == "Lambda" && m.IsGenericMethod).First();
Type genericArguments = typeof(Action<,>).MakeGenericType(typeSet, entity.GetType());
MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(genericArguments);
dynamic objectSet = set;
dynamic returnValue = genericMethodInfo.Invoke(null, new object[] { methodCall, new ParameterExpression[] { paramo, parami } });
var action = returnValue.Compile();
action(objectSet, entity);

如果你使用的是。net 4.0,你可以使用"dynamic"关键字——这是最好的和最高效的方法。它看起来像这样:

Type contextType = (context as Object).GetType();
dynamic set = (contextType.GetProperty(entitySetName)).GetValue(context, null);
set.Add(args);

我不确定我完全理解你的代码,所以不确定这就是你想要做的,但这是一般的想法。

进一步阅读:http://msdn.microsoft.com/en-us/library/dd264736.aspx