我想查询一个表(Accounts),并作为查询的一部分从另一个表(AccountPositions)中获取总数(Total)。如何将该SQL查询重写为linq查询?就像添加一个按语句分组一样容易...但是按用法分组使我感到困惑。
select
(select sum(ap.Quantity * ap.LastPrice) from AccountPositions ap
where ap.AccountId = a.Accountid and ap.IsOpen = 0) as Total,
a.AccountId, a.Username, a.FirstName, a.LastName, a.AccountNumber
from Accounts a
where a.IsTrading = 1
类似的东西
var query = (from a in _context.Accounts
join ap in _context.AccountPositions on ap.AccountId = a.AccountId
where a.IsTrading == true && and ap.IsOpen == true
select new {
Total = ap.Sum(r => r.Quantity * r.LastPrice),
AccountId = a.AccountId,
Username = a.Username,
FirstName = a.FirstName,
LastName = a.LastName,
AccountNumber = a.AccountNumber
});
所需结果:
Total AccountId Username FirstName LastName AccountNumber
2500 496 brice Brian Rice U399445
160 508 jdoe John Doe U555322
表格:
Accounts
AccountId Username FirstName LastName AccountNumber IsTrading
496 brice Brian Rice U399445 1
498 bmarley Bob Marley U443992 0
508 jdoe John Doe U555332 1
AccountPositions
AccountPositionId AccountId Quantity LastPrice IsOpen
23 496 10 200 1
24 496 15 48 0
25 508 8 20 1
26 498 18 35 1
27 496 5 100 1
答案 0 :(得分:2)
如何将该SQL查询重写为linq查询?是否像通过语句添加组一样容易...
这甚至更容易,因为所讨论的SQL查询在select子句中使用单个聚合返回相关子查询,因此对LINQ的转换实际上是一对一的-只需使用相应的C#运算符,并记住在LINQ {{ 1}}走到最后。像select
这样的聚合方法在LINQ 查询语法之外:
Sum
但是LINQ允许您将查询语法与方法语法混合使用,因此var query =
from a in _context.Accounts
where a.IsTrading
select new
{
Total = (from ap in _context.AccountPositions
where ap.AccountId == a.AccountId && ap.IsOpen
select ap.Quantity * ap.LastPrice).Sum(),
a.AccountId,
a.Username,
a.FirstName,
a.LastName,
a.AccountNumber
};
部分可以使用下面这样的形式更自然地编写:>
Sum
最后,如果您使用的是Entity Framework,则Total = _context.AccountPositions
.Where(ap => ap.AccountId == a.AccountId && ap.IsOpen)
.Sum(ap => ap.Quantity * ap.LastPrice),
和Account
之间的关系将由类似的
AccountPosition
public ICollection<AccountPosition> AccountPositions { get; set; }
类中的 导航属性。这样就可以忽略诸如Account
之类的联接(相关)条件-它们将自动应用,并且仅关注查询逻辑(请参见Don’t use Linq’s Join. Navigate!),例如
ap.AccountId == a.AccountId
在LINQ查询中,EF集合导航属性表示所谓的grouped join-独特的LINQ功能(至少在SQL中没有直接等效的功能)。在LINQ查询语法中,它表示为Total = a.AccountPositions.Where(ap => ap.IsOpen).Sum(ap => ap.Quantity * ap.LastPrice),
+ join
子句。假设您需要多个集合。分组联接将帮助您实现不重复相关部分的功能。
因此,对于您的模型,使用分组联接的查询将像这样开始:
into
从这里开始,您有2个变量-from a in _context.Accounts
join ap in _context.AccountPositions on a.AccountId equals ap.AccountId into accountPositions
代表a
,而Account
代表与accountPositions
相关的AccountPosition
的集合。
但是您只对空缺职位感兴趣。为了避免重复该条件,可以使用另一个LINQ 查询语法构造-let子句。因此查询继续使用两个过滤器:
Account
现在,您拥有生成最终结果的所有信息,例如:
where a.IsTrading
let openPositions = accountPositions.Where(ap => ap.IsOpen)