我有以下代码:
var newProducts = _summaryRepository.GetFilteredSummaries(manufacturerIds, countryIds, categoryIds,
null, widgetIds, startDate, null).Where(s => s.Product.ProductCountries.FirstOrDefault(pc => pc.CountryId == s.CountryId).CreatedAt >= startDate.Value)
.GroupBy(s => new { widgetId = s.widgetId, ProductId = s.ProductId });
如果我有条件显示所有我想从GroupBY中取出以下内容:
WidgetId = s.WidgetId
现在它将是:
var newProducts = _summaryRepository.GetFilteredSummaries(manufacturerIds, countryIds, categoryIds,
null, widgetIds, startDate, null).Where(s => s.Product.ProductCountries.FirstOrDefault(pc => pc.CountryId == s.CountryId).CreatedAt >= startDate.Value)
.GroupBy(s => new {ProductId = s.ProductId });
有很多代码依赖于newProducts,当我创建了一个if语句并将var newProducts放在了outerscrope中时,它会阻止所有工作。
我知道这可能是个愚蠢的问题,但我怎么能用最少的重复代码来做呢?
当我这样做时,我是否宣布变量是错误的:
var newProducts;
if(model.allWidgets)
{newProducts = _summaryRepository.GetFilteredSummaries(manufacturerIds, countryIds, categoryIds,
null, WidgetIds, startDate, null).Where(s => s.Product.ProductCountries.FirstOrDefault(pc => pc.CountryId == s.CountryId).CreatedAt >= startDate.Value)
.GroupBy(s => new {ProductId = s.ProductId });}
else
{
newProducts = _summaryRepository.GetFilteredSummaries(manufacturerIds, countryIds, categoryIds,
null, WidgetIds, startDate, null).Where(s => s.Product.ProductCountries.FirstOrDefault(pc => pc.CountryId == s.CountryId).CreatedAt >= startDate.Value)
.GroupBy(s => new { WidgetId = s.WidgetId, ProductId = s.ProductId });
}
答案 0 :(得分:4)
当model.allWidgets为true时,您可以将GroupBy更改为忽略s.WidgetId:
query.GroupBy(s => new { WidgetId = model.allWidgets ? 0 : s.WidgetId, ProductId = s.ProductId });
答案 1 :(得分:2)
从LINQ Conditional Group开始,您可以为分组(WidgetId = 0
)添加“null”,从而导致GroupBy
在两种情况下都返回相同的匿名分组类型:
var newProducts = _summaryRepository.GetFilteredSummaries(...)
.Where(s => ...)
var groupedProducts = newProducts.GroupBy(s =>
{
if(model.allWidgets)
{
return new
{
ProductId = s.ProductId,
WidgetId = 0,
};
}
else
{
return new
{
ProductId = s.ProductId,
WidgetId = s.WidgetId,
};
}
});
当然,作为just-added answer indicates,使用条件运算符可以大大减少这一点:
var groupedProducts = newProducts.GroupBy(s =>
new
{
ProductId = s.ProductId,
WidgetId = model.allWidgets ? 0 : s.WidgetId,
});
此类型仍然是匿名的,因此无法直接从您的代码访问,因此为了从方法返回它,请引入一个类来保存该组:
public class ProductGrouping
{
public int ProductId { get; set; }
public int? WidgetId { get; set; }
}
public IGrouping<ProductGrouping, Summary> GetGroupedSummaries()
{
return _summaryRepository.GetFilteredSummaries(...)
.Where(s => ...)
.GroupBy(s => new ProductGrouping
{
ProductId = s.ProductId,
WidgetId = model.allWidgets ? (int?)null : s.WidgetId,
});
}
答案 2 :(得分:1)
您尝试做的事情实际上是不可能的,因为您的2个查询会返回不同的匿名类型,除非您愿意将结果分配回object
类型的变量,这似乎不太有用(或dynamic
,但是你失去了使用LINQ的编译时间好处。
为了能够使用var
关键字,编译器必须能够确定声明类型,这意味着您必须在声明变量的位置提供赋值。
正如Implicitly Typed Local Variables的文档中所述:
var
关键字指示编译器从初始化语句右侧的表达式 推断变量 的类型。
还有......
重要的是要了解
var
关键字并不代表“变种” ,并不表示该变量是松散输入的,或者是界。它只是意味着编译器确定并分配最合适的类型。