通用表达式抽象问题
我有以下方法SetMapping()
,用于使用表达式定义一些映射设置。
public class AggregateMap { protected Expression<Func<IUpdateConfiguration, object>> graphMapping; protected void SetMapping(Expression<Func<IUpdateConfiguration, object>> mapping) { graphMapping = mapping; } }
调用代码示例:
SetMapping(map => map.OwnedCollection(root => root.ChildEntities));
上面的工作很好,但我想通过提供SetOwnedCollectionMapping()
进一步抽象这个方法。 这意味着调用代码可以提供更基本的表达式。
进一步抽象的方法:
protected void SetOwnedCollectionMapping(Expression<Func<TDataEntity, ICollection>> mapping) { graphMapping = map => map.OwnedCollection(mapping); }
调用代码示例:
SetOwnedCollectionMapping(root => root.ChildEntities);
然后,通过在Entity Framework DbContext实例上调用以下方法,将此graphMapping
字段用于外部库(RefactorThis.GraphDiff):
public static void UpdateGraph(this DbContext context, T entity, Expression<Func<IUpdateConfiguration, object>> mapping) where T : class;
在运行时抛出以下exception:
RefactorThis.GraphDiff.dll中出现“System.InvalidCastException”类型的exception,但未在用户代码中处理
附加信息:无法将类型为“System.Reflection.RtFieldInfo”的对象强制转换为“System.Reflection.PropertyInfo”。
我必须混淆我的generics类型,但我看不出旧的和新的实现之间的区别。
这是OwnedCollection
方法的签名:
public static IUpdateConfiguration OwnedCollection(this IUpdateConfiguration config, Expression<Func<T, System.Collections.Generic.ICollection>> expression);
编辑:添加UpdateGraph
信息以提问。
两个实现之间的关键区别在于第二个捕获方法参数,而第一个没有。 该参数作为字段存储在闭包中,并且该字段访问的存在可能导致RefactorThis.GraphDiff.dll
出现问题。
尝试更改第二个实现,如下所示:
protected void SetOwnedCollectionMapping(Expression>> mapping) { // // Hack to resolve the `OwnedCollection` extension method. // Expression, object>> template = _ => _.OwnedCollection(mapping); var map = Expression.Parameter( typeof(IUpdateConfiguration), "map"); graphMapping = Expression.Lambda, object>>( Expression.Call( ((MethodCallExpression)template.Body).Method, map, Expression.Quote(mapping)), map); }
然后, graphMapping
的值应与第一个实现的值相同。