【发布时间】:2019-08-19 13:46:01
【问题描述】:
想知道为什么 LINQ 没有 Left Join 方法。我一直试图用无数关于 SO 的例子来解决这个问题,但没有这样的运气。其他示例显示了一个连接的简单示例。如果我对连接进行分组,那么我只会在 select 语句中获得对 TradeCountries 表的引用。
作为 LINQ 的新手,我可以在 4 小时前用一个简单的 SELECT 语句完成这项工作,但在这里我试图弄清楚为什么 LeftJoin 方法被排除在 LINQ 之外。
需要更改带有“LeftJoin”的行以使其正常工作?
/*
* GetTop5Distributors
@param int array of series IDs
*/
public List<TopDistributors> Get5TopDistributors(IEnumerable<int> seriesIds)
{
_context = new MySQLDatabaseContext();
var result = _context.TradesTrades
.Join(_context.TradesSeries, tt => tt.SeriesId, ts => ts.Id, (tt, ts) => new { tt, ts })
.Join(_context.TradesTradeDistributors, tsd => tsd.tt.Id, ttd => ttd.TradeId,
(tsd, ttd) => new { tsd, ttd })
.Join(_context.TradesOrganisations, tsdto => tsdto.ttd.DistributorId, to => to.Id,
(tsdto, to) => new { tsdto, to })
.LeftJoin(_context.TradesCountries, tsdc => tsdc.to.CountryId, tc => tc.Id,
(tsdc, tc) => new {tsdc, tc})
.Where(x => seriesIds.Contains(x.tsdc.tsdto.tsd.tt.SeriesId))
.Where(x => x.tsdc.tsdto.tsd.tt.FirstPartyId == null)
.Where(x => x.tsdc.tsdto.tsd.tt.Status != "closed")
.Where(x => x.tsdc.tsdto.tsd.tt.Status != "cancelled")
.GroupBy(n => new { n.tsdc.tsdto.tsd.tt.SeriesId, n.tsdc.tsdto.ttd.DistributorId })
.Select(g =>
new TopDistributors
{
SeriesId = g.Key.SeriesId,
DistributorName = g.Select(i => i.tsdc.to.Name).Distinct().First(),
IsinNickname = g.Select(i => i.tsdc.tsdto.tsd.ts.Nickname).Distinct().First(),
CountryName = g.Select(i => i.tc.Name).Distinct().First(),
CommissionTotal = Math.Ceiling(g.Sum(i => i.tsdc.tsdto.ttd.Commission))
}
)
.OrderByDescending(x => x.CommissionTotal)
.Take(5)
.ToList();
return result;
}
这是一个相当简单的 select 语句,它需要几个数量级或数量级的时间来转换为 LINQ。
SELECT
trades_trades.series_id,
trades_organisations.`name`,
trades_series.nickname,
trades_countries.name as Country_Name,
SUM(trades_trade_distributors.commission) as Commission_Total
FROM
trades_trades
JOIN trades_series
ON trades_series.id = trades_trades.series_id
JOIN trades_trade_distributors
ON trades_trades.id = trades_trade_distributors.trade_id
JOIN trades_organisations
ON trades_trade_distributors.distributor_id = trades_organisations.id
LEFT JOIN trades_countries
ON trades_organisations.country_id = trades_countries.id
WHERE trades_trades.series_id IN (
17,
18)
AND trades_trades.first_party_id IS NULL
AND trades_trades.status <> 'closed'
AND trades_trades.status <> 'cancelled'
GROUP BY trades_trades.series_id, trades_trade_distributors.distributor_id
ORDER BY Commission_Total DESC
【问题讨论】:
-
您需要
GroupJoin。也许这可能有用:Perform left outer joins -
我看过这些例子。其他示例显示了一个连接的简单示例。如果我对连接进行分组,那么我只会在 select 语句中获得对 TradeCountries 表的引用。
-
使用方法链接语法并以这种方式传递变量非常繁琐,因为您需要使用
new {}(匿名对象)语法传递它们。也许您可以使用查询语法重写您的查询。它还使它更具可读性。 -
也许我的SQL to LINQ Recipe 可以帮助你?