【发布时间】:2020-02-19 22:50:03
【问题描述】:
我有一个现有的 LINQ to SQL 查询,我试图在其中允许不同的分组:
var result= dc.Report_Data
.Where(x => x.Year == Year)
.Where(x => x.Month >= Month)
.GroupBy(grouping)
.Select(g => new ReportViewModel(){
Month = g.Key.Month,
Option1 = g.Key.Option1,
Option2 = g.Key.Option2,
Amount = g.Sum(x => x.Amount)
})
.ToList();
我需要允许根据外部参数对不同的属性集进行分组。我设置了一个默认值,然后使用这样的条件:
Expression<Func<Report_Data, TResult>> grouping = g => new {g.Month, Option1 = g.prop1, Option2 = g.prop2};
if (userParameter == "X"){
grouping = g => new {g.Month, Option1 = g.prop3, Option2 = g.prop4};
} else if (userParameter == "Y") {
grouping = g => new {g.Month, Option1 = g.prop5, Option2 = g.prop6};
}
然后我将grouping 传递给上面的查询。问题是我在分组中有一个匿名类型,当我使用TResult 作为结果类型时出现Expression<Func<Report_Data, TResult>> 错误。
有没有办法使用这种表达式委托格式并指定通用或匿名结果类型? (最好不必为每种结果类型创建一个类) 还是我应该通过其他机制允许不同的分组?
【问题讨论】:
-
大多数匿名类型的问题都可以通过定义自己的命名类型来解决。我不是 100% 确定,但我认为你在这里构造不同的匿名类型,因为你在两个地方定义它。但是要将其分配给分组,它们必须相等。除了将分组作为变量之外,您还可以将“if”放在 IQueryable
链中。 -
我不反对。如果可能,我尝试使用泛型的原因是因为这是我正在修改的现有代码库,并且我将更新多个使用匿名类型的查询。因此,如果我可以减少改变而侥幸,我愿意这样做。如果最终证明情况更糟,我将通过并开始创建一堆命名类型。
-
您不能让(非泛型)方法返回匿名类型,并且您不能后退(或上一级)因为
Grouping返回一个IGrouping,这取决于匿名类型也是如此。但是您可以通过将Option1和Option2设为固定类型并将各种prop*字段转换为该类型(如果它们不相似)来标准化密钥类型。ReportViewModel.Option1和ReportViewModel.Option2有哪些类型?
标签: c# sql linq lambda delegates