使用LINQ中的“Not Exists”子句帮助重写现有的SQL查询

时间:2010-03-10 02:37:25

标签: asp.net-mvc linq linq-to-sql

我在使用“Not Exist”子句将现有TSQL查询转换为用于ASP.NET MVC应用程序的工作LINQ时遇到问题。

这是我现有的查询。

SELECT
    OrgID,
    ContentID,
    FriendlyTitle

FROM
    ContentRollup CR

WHERE
    OrgID = @sOrgID
    OR
    (
        OrgID = '*'
        AND NOT EXISTS (
            SELECT NULL
            FROM ContentRollup
            WHERE OrgID = @sOrgID AND ContentID = CR.ContentID
        )
    )

正在查询的表ContentRollup如下所示:

OrgID  ContentID    FriendlyTitle
------  ----------  ----------------
*       xxx111      Default text 1
*       xxx222      Default text 2
*       xxx333      Default text 3
AAA     xxx333      AAA text 3
BBB     xxx333      BBB text 3

简而言之,这是家庭构建CMS的一部分,它提供同一内容的Org特定变体。多年来,它一直为我们服务。 OrgID为*的记录是所有Orgs的默认值,但如果传入OrgID,它们将被覆盖。

例如,如果我没有传入任何内容或CCC,则会返回三个*记录。如果我传入AAA,那么前两个默认记录将返回以及AAA记录。如果我传入BBB,前两个默认记录将返回以及BBB记录。

那么......我在世界上如何将其翻译成LINQ?我已经尝试过各种版本的.Contains和.Except,但无法使用多种标准。

我最接近的是

var result = from c in DB.Content
         where (
            c.OrgID == orgID
            ||
            (
                c.OrgID == "*"
                && !(from c1 in DB.Content
                     select c1.OrgID)
                     .Contains(orgID)
                    )
            )
         select c;

但我不能在我想要的地方获得“AND ContentID = CR.ContentID”标准。

1 个答案:

答案 0 :(得分:3)

不存在转换为!Any():

context.ContentRollup.
    Where(cr => 
        (cr.OrgID == sOrgId) 
        || 
        (
            (cr.OrgID == '*') 
            && 
            (!context.ContentRolup.Any(cr2 => 
                 (cr2.OrgID == sOrgId) && 
                 (cr2.ContentID == cr.ContentID))
            )
        ).ToList()