我有一个Linq查询,该查询使用let语句,从该语句派生几个子查询。目前,我正在执行3个子查询以使用3个相同的联接来得出计数,并且我希望仅通过一个联接就可以将它们组合成一个子查询。我有这样的东西:
let TheFruits = (complex query).ToList(),
Counter1 = (from TheTable in MyDC.SomeTable
join x in Thefruits on
TheTable.FruitID equals x.FruitID
where x.Field1 == 1
select x).Count(),
Counter2 = (from TheTable in MyDC.SomeTable
join x in Thefruits on
TheTable.FruitID equals x.FruitID
where x.Field2 == 2
select x).Count(),
Counter3 = (from TheTable in MyDC.SomeTable
join x in Thefruits on
TheTable.FruitID equals x.FruitID
where x.Field3 == 3
select x).Count(),
为了替换3个联接,我想写这样的东西,但是我没有在对象属性中得到扩展方法:
let TheFruits = (complex query).ToList(),
TheCounterObject = (from TheTable in MyDC.SomeTable
join x in Thefruits on
TheTable.FruitID equals x.FruitID
select new CounterObject()
{
Count1 = x.Where....Count(),
Count2 = x.Where....Count(),
Count3 = x.Where....Count(),
//not getting .Where extension
}).Single()
问题是我没有扩展方法,只是表列。在我提供的简单示例中,.Where子句仅匹配一个条件,但是在我的实际子查询中,涉及到DateTimes和其他条件。
如何在对象映射阶段运行计数?
进一步研究之后,我现在有了以下内容:
let TheFruits = (complex query).ToList(),
TheCounterObject = (from TheTable in MyDC.SomeTable
join x in TheFruits on
TheTable.FruitID equals x.FruitID
into TheSubFruits
select new CounterObject()
{
Count1 = TheSubFruits.Where(x.FruitID == TheTable.FruitID && other conditions).Count(),
Count2 = TheSubFruits.Where(x.FruitID == TheTable.FruitID && other conditions).Count(),
Count3 = TheSubFruits.Where(x.FruitID == TheTable.FruitID && other conditions).Count()
}).First()
问题在于计数是错误的,如果我使用.Single()而不是.First(),还会收到“序列包含多个元素”错误。
为什么该子查询返回的计数与3个子查询的计数相同?我需要更改什么?
答案 0 :(得分:0)
您在.Where
上没有获得x
扩展名,因为在那一点上,x不再可枚举。 x
代表每个单独的水果,但您想将.Where
应用于所有水果。为此,您可以进行联接,然后执行我在编辑中显示的计数。
如果您需要为不同的条件提供不同的计数,我建议使用以下方法:
var joined = (from TheTable in MyDC.SomeTable
join x in Thefruits on
TheTable.FruitID equals x.FruitID
select x).ToList();
var count1 = joined.Where(...).Count();
var count2 = joined.Where(...).Count();
var count3 = joined.Where(...).Count();
这将允许您具有多个条件,条件甚至可以重叠并在需要时计数相同的对象。它与您最初拥有的资源非常相似,但是只执行一次连接。
再考虑一下之后,您可以执行与第二个示例中显示的非常相似的操作,然后将其与合计相结合,以获得所需的结果。
var counts = (from TheTable in MyDC.SomeTable
join x in Thefruits on
TheTable.FruitID equals x.FruitID
select new {
// Calculate whether this object be included in each count
Count1 = x.FruitId == 1 ? 1 : 0,
Count2 = x.FruitId == 2 ? 1 : 0,
Count3 = x.FruitId == 3 ? 1 : 0
}).Aggregate((acc, i) => new {
Count1 = acc.Count1 + i.Count1,
Count2 = acc.Count2 + i.Count2,
Count3 = acc.Count3 + i.Count3
});
这是其中一个工作的example,具有伪数据类,现在具有联接。这可能与您要查找的内容最接近,因为它仅执行一次连接,将对象视为进行映射的对象,并允许多个复杂条件。