将T-SQL语句转换为Linq to Sql:计数减法实现难题
两种T-SQL对应的Linq to Sql实现
子查询方式(对应SQL 1)
这种方式和原SQL逻辑完全匹配,直接在选择逻辑中嵌入计数子查询,实现起来最直观:
// 定义目标事件ID和有效参与者状态集合 int targetEventId = /* 替换为你的E__ID值 */; var validStatuses = new[] { "B", "C" }; // 计算可用位置,返回单行单列的整数结果 int availablePlaces = (from e in db.Events where e.E__ID == targetEventId select e.Places - db.EventParticipants.Count(ep => ep.E__ID == targetEventId && validStatuses.Contains(ep.EP_STAT))) .Single();
如果无法确保目标ID一定存在于Events表中,可以用SingleOrDefault()返回int?类型,避免抛出异常。
JOIN/GROUP方式(对应SQL 2)
对应原SQL的内连接分组逻辑,注意原SQL使用内连接,因此当没有符合条件的参与者时,不会返回任何结果(和SQL 1的行为有差异,SQL 1会返回Places - 0):
int targetEventId = /* 替换为你的E__ID值 */; var validStatuses = new[] { "B", "C" }; int? availablePlaces = (from e in db.Events join ep in db.EventParticipants on e.E__ID equals ep.E__ID where e.E__ID == targetEventId && validStatuses.Contains(ep.EP_STAT) group e by e.Places into groupedData select groupedData.Key - groupedData.Count()) .SingleOrDefault();
如果要让该实现和SQL 1行为完全一致(无符合条件参与者时返回Places原值),需要改用左连接:
int targetEventId = /* 替换为你的E__ID值 */; var validStatuses = new[] { "B", "C" }; int availablePlaces = (from e in db.Events where e.E__ID == targetEventId join ep in db.EventParticipants on e.E__ID equals ep.E__ID into participantGroup from ep in participantGroup.DefaultIfEmpty() group ep by e.Places into groupedData select groupedData.Key - groupedData.Count(ep => ep != null && validStatuses.Contains(ep.EP_STAT))) .Single();
内容的提问来源于stack exchange,提问作者kevmull
相关产品推荐
相关产品推荐

