如何在 Linq 方法语法中捕获变量?
How do I capture a variable in Linq method syntax?
我有以下 Linq 查询...
Proposals.OrderByDescending (p => p.ID)
.First ()
.Proposal_ProductConfigurations
.Select(ppc => ppc.ProductConfigurationHistory)
.Where(pch => pch.Active)
.Select(pch => pch.ProductConfiguration)
.Where(pc => pc.Active)
.SelectMany(pc => pc.ProductConfigurations_PriceBookEntries)
.Where(pcpb => pcpb.Active)
.OrderBy(pcpb => pcpb.PriceBook.ProductCode)
.GroupBy(pcpb => pcpb.PriceBook.ID)
.Select (pcpb => new {
Code = pcpb.First().PriceBook.ProductCode,
Description = pcpb.First().PriceBook.Description,
Quantity = pcpb.Sum (pcpb1 => (pcpb1.Quantity ?? 0)),
})
...不太正确,因为 ppc.Quantity 实体的数量 属性 需要在最后一行中使用。
我真正想做的是这行...
Quantity = pcpb.Sum (pcpb1 => (pcpb1.Quantity ?? 0) * ppc.Quantity),
...但是我当然不能,因为 ppc 不在范围内。
我如何捕获 ppc.Quantity 并在最后一行中使用它?我认为这可以通过流畅的语法来完成,但我从未使用过它,也没有设法生成编译器喜欢的任何代码!
首先你可以简化下面的部分
.Select(ppc => ppc.ProductConfigurationHistory)
.Where(pch => pch.Active)
.Select(pch => pch.ProductConfiguration)
.Where(pc => pc.Active)
至
.Where(ppc => ppc.ProductConfigurationHistory.Active
&& ppc.ProductConfigurationHistory.ProductConfiguration.Active)
并且您将维护 ppc
的结果集合而不是 pc
。
此时您需要使用具有结果选择器和集合选择器的 SelectMany
重载来保留 ppc
.SelectMany(
ppc => ppc.ProductConfigurationHistory
.ProductConfiguration
.ProductConfigurations_PriceBookEntries,
(ppc, pcpb) => new { ppc, pcpb })
然后你只需要使用那个新的匿名 class 你就会得到这个
Proposals.OrderByDescending (p => p.ID)
.First ()
.Proposal_ProductConfigurations
.Where(ppc => ppc.ProductConfigurationHistory.Active
&& ppc.ProductConfigurationHistory.ProductConfiguration.Active)
.SelectMany(
ppc => ppc.ProductConfigurationHistory
.ProductConfiguration
.ProductConfigurations_PriceBookEntries,
(ppc, pcpb) => new { ppc, pcpb })
.Where(anon => anon.pcpb.Active)
.OrderBy(anon => anon.pcpb.PriceBook.ProductCode)
.GroupBy(anon => anon.pcpb.PriceBook.ID)
.Select (grp => new {
Code = grp.First().pcpb.PriceBook.ProductCode,
Description = grp.First().pcpb.PriceBook.Description,
Quantity = grp.Sum(anon => (anon.pcpb.Quantity ?? 0) * anon.ppc.Quantity),
})
我有以下 Linq 查询...
Proposals.OrderByDescending (p => p.ID)
.First ()
.Proposal_ProductConfigurations
.Select(ppc => ppc.ProductConfigurationHistory)
.Where(pch => pch.Active)
.Select(pch => pch.ProductConfiguration)
.Where(pc => pc.Active)
.SelectMany(pc => pc.ProductConfigurations_PriceBookEntries)
.Where(pcpb => pcpb.Active)
.OrderBy(pcpb => pcpb.PriceBook.ProductCode)
.GroupBy(pcpb => pcpb.PriceBook.ID)
.Select (pcpb => new {
Code = pcpb.First().PriceBook.ProductCode,
Description = pcpb.First().PriceBook.Description,
Quantity = pcpb.Sum (pcpb1 => (pcpb1.Quantity ?? 0)),
})
...不太正确,因为 ppc.Quantity 实体的数量 属性 需要在最后一行中使用。
我真正想做的是这行...
Quantity = pcpb.Sum (pcpb1 => (pcpb1.Quantity ?? 0) * ppc.Quantity),
...但是我当然不能,因为 ppc 不在范围内。
我如何捕获 ppc.Quantity 并在最后一行中使用它?我认为这可以通过流畅的语法来完成,但我从未使用过它,也没有设法生成编译器喜欢的任何代码!
首先你可以简化下面的部分
.Select(ppc => ppc.ProductConfigurationHistory)
.Where(pch => pch.Active)
.Select(pch => pch.ProductConfiguration)
.Where(pc => pc.Active)
至
.Where(ppc => ppc.ProductConfigurationHistory.Active
&& ppc.ProductConfigurationHistory.ProductConfiguration.Active)
并且您将维护 ppc
的结果集合而不是 pc
。
此时您需要使用具有结果选择器和集合选择器的 SelectMany
重载来保留 ppc
.SelectMany(
ppc => ppc.ProductConfigurationHistory
.ProductConfiguration
.ProductConfigurations_PriceBookEntries,
(ppc, pcpb) => new { ppc, pcpb })
然后你只需要使用那个新的匿名 class 你就会得到这个
Proposals.OrderByDescending (p => p.ID)
.First ()
.Proposal_ProductConfigurations
.Where(ppc => ppc.ProductConfigurationHistory.Active
&& ppc.ProductConfigurationHistory.ProductConfiguration.Active)
.SelectMany(
ppc => ppc.ProductConfigurationHistory
.ProductConfiguration
.ProductConfigurations_PriceBookEntries,
(ppc, pcpb) => new { ppc, pcpb })
.Where(anon => anon.pcpb.Active)
.OrderBy(anon => anon.pcpb.PriceBook.ProductCode)
.GroupBy(anon => anon.pcpb.PriceBook.ID)
.Select (grp => new {
Code = grp.First().pcpb.PriceBook.ProductCode,
Description = grp.First().pcpb.PriceBook.Description,
Quantity = grp.Sum(anon => (anon.pcpb.Quantity ?? 0) * anon.ppc.Quantity),
})