【发布时间】:2016-06-16 17:58:12
【问题描述】:
我正在尝试使用以下语句对两组数据进行外部联接:
var destinationList = inners.GroupJoin(outers, inner => inner.JoinField, outer => outer.JoinField,
(inner, outerList) =>
outerList.Select(outer => new DestinationModel { Id = inner.JoinField, AggregationField = outer.DataField })
.DefaultIfEmpty(new DestinationModel { Id = inner.JoinField })).SelectMany(destination => destination).ToList();
这可以正常工作,没有问题,但我最终需要将其转换为表达式树以允许数据集和字段更改。
我的数据模型如下所示:
内部模型: 公共类内部模型 { 公共 int JoinField; 公共十进制数据字段; }
外型: 公共类 OuterModel { 公共 int JoinField; 公共十进制数据字段; }
目标模型: 公共类目的地模型 { 公共整数 ID; 公共十进制聚合字段; }
inners 是List<InnerModel>
外部是List<OuterModel>
我已经完成了大部分的工作,但我在最后一步还不够。这是我目前所拥有的:
// Declare variables
var innerParameter = Expression.Parameter(typeof (InnerModel), "inner");
var innerSelect = Expression.Lambda<Func<InnerModel, int>>(Expression.Field(innerParameter, "JoinField"), innerParameter);
var outerParameter = Expression.Parameter(typeof (OuterModel), "outer");
var outerListParameter = Expression.Parameter(typeof (IEnumerable<OuterModel>), "outerList");
var outerSelect = Expression.Lambda<Func<OuterModel, int>>(Expression.Field(outerParameter, "JoinField"), outerParameter);
var existingBinding = Expression.MemberInit(Expression.New(typeof (DestinationModel)), Expression.Bind(typeof (DestinationModel).GetField("Id"), Expression.Field(innerParameter, "JoinField")));
// Create lambdas
var selector = Expression.Lambda<Func<OuterModel, DestinationModel>>(existingBinding, outerParameter);
var selectMethod = typeof (Enumerable).GetMethods().First(x => x.Name == "Select" && x.GetParameters().Length == 2).MakeGenericMethod(typeof(OuterModel), typeof(DestinationModel));
var selectCall = Expression.Call(selectMethod, outerListParameter, selector);
// Create the inner key selector for the GroupJoin method
var innerKeySelector = Expression.Lambda(selectCall, innerParameter, outerListParameter);
到目前为止一切正常。当我尝试将 innerKeySelector 插入原始语句时:
var result = inners.GroupJoin(outers, innerSelect.Compile(), outerSelect.Compile(), (inner, outerList) => outerList.Select(outer => new DestinationModel {Id = inner.JoinField, AggregationField = outer.DataField}).DefaultIfEmpty(new DestinationModel {Id = inner.JoinField})).SelectMany(destination => destination).ToList();
我得到一个编译错误:
无法从用法中推断方法“Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>)”的类型参数。尝试明确指定类型参数。
我知道我只是遗漏了一些明显的东西,但是在研究了几个小时之后,我没有看到它。有人能指出我正确的方向吗?
【问题讨论】:
-
除了必须将模型类重命名为
xxxTestModel之外,发布的代码没有任何编译器错误。 -
我修改了代码中的类名,并简化了一些调用,但还是报错。
标签: c# reflection expression-trees system.reflection