views:

147

answers:

1

I'm having trouble translating an existing TSQL query with a "Not Exist" clause into working LINQ for use in an ASP.NET MVC app.

Here's my existing query.

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
        )
    )

The table being queried, ContentRollup, looks like this:

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

In a nutshell, this is part of a home-build CMS that serves Org-specific variations of the same piece of content. It has served us solidly for years. Records with OrgID of * are defaults for all Orgs, but they will be overridden if an OrgID is passed in.

For example, if I pass in nothing or CCC, the three * records will be returned. If I pass in AAA, then the first two default records will return as well as the AAA record. If I pass in BBB, the first two default records will return as well as the BBB record.

So... how in the world do I translate this to LINQ? I've tried various version of .Contains and .Except but can't get it to work with multiple criteria.

The closest I've gotten is

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;

but I can't get the "AND ContentID = CR.ContentID" criteria where I want it.

+3  A: 

Not exists translates to !Any():

context.ContentRollup.
    Where(cr => 
        (cr.OrgID == sOrgId) 
        || 
        (
            (cr.OrgID == '*') 
            && 
            (!context.ContentRolup.Any(cr2 => 
                 (cr2.OrgID == sOrgId) && 
                 (cr2.ContentID == cr.ContentID))
            )
        ).ToList()
LukLed
Perfect. Exactly what I needed.
Mike