如何将包含“NOT IN”约束的SQL语句转换为其等效的LINQ?

时间:2011-06-20 14:49:17

标签: c# sql linq entity-framework

我一直在使用Linq大约一年,而且我只是对SQL的粗暴理解。所以下面的问题可能是陈腐的,我现在为此道歉。但是在工作中我被要求找出在下面的sql上使用linq的最高效的方法。我需要一些帮助。

我有一个Client表和一个ClientParticiaption表。 ClientParticiaption表标识参与特殊培训计划的客户。我需要确定哪些客户没有参加特殊培训计划。这是有效的SQL:

SELECT *
FROM Client
WHERE ClientControlID NOT IN
(
  SELECT ClientControlID
  FROM ClientParticipation
)

我无法将其转换为等效的linq语句。我想我应该使用Except运算符,但我不确定在这种情况下如何。任何想法都会非常有用。

这就是我目前正在做的事情,这是有效的,但我怀疑这不是很有效。注意,我正在使用实体框架,我可能错误地认为解决此问题与EF无关。

IList<int> clientControlIDs =
    ClientArngmt.Select(
    cac => cac.ClientControlID ).ToList();

IList<int> particiaptionClientArngmtIDs =
    Participations.Select(
    cap => cap.ClientArngmtID ).ToList();

IEnumerable<int> notParticipatingClientArngmtIDs =
    clientArngmtIDs.Except(
    particiaptionClientArngmtIDs );

2 个答案:

答案 0 :(得分:3)

您可以使用where语句,例如

        IList<Client> clients = (from cac in ClientArngmt
                                 where !(Participations.Select(cap => ClientArngmtID).Contains(cac.ClientControlID))
                                 select cac).ToList();

答案 1 :(得分:1)

第一个解决方案:

ClientArngmt
 .Where(c => !Participations.Select(p => p.ClientArngmtID).Contains(c.ClientControlID))
 .Select(c => c);

第二个解决方案:

Participations
 .Where(p => !p.Clients.Any()) // Just assuming Clients is the ObjectSet name for ClientArngmt
 .SelectMany(p => p.Clients)
 .Distinct(); // If you want to get them distinct