Question

I'm pretty new with linq and i would like to do this query :

select *
FROm dbo.PremiseProviders p
where p.premiseProviderId IN
  (select a.premiseproviderId
  FROM dbo.PremiseProviderAddresses a, dbo.premiseProviderAddressVersions v
  where a.premiseprovideraddressId = v.premiseprovideraddressId
  and v.postcode = '84280')

But i have no idea how to do the IN part, with the second Select, can someone help? Thx

Was it helpful?

Solution

Usually Contains method is translated into IN operator. E.g. you have collection of integers 2, 3, 7 then

   where ids.Contains(p.premiseProviderId)

Will be translated to

   WHERE p.premiseProviderId IN (@p1, @p2, @p3)

But EF is pretty clever and same approach with your query

from p in db.PremiseProviders
where (from a in db.PremiseProvideAddresses
       join v in db.PremiseProviderAddressVersions
           on a.premiseprovideraddressId equals v.premiseprovideraddressId
       where v.postcode == "84280"
       select a.premiseproviderId).Contains(p.premiseProviderId)
select p

Will be translated into better SQL than you have - it will generate EXISTS subquery. Something like

SELECT [t0].[premiseProviderId], [t0].[Foo], [t0].[Bar]
FROM [PremiseProviders] AS [t0]
WHERE EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [PremiseProvideAddresses] AS [t1]
    INNER JOIN [PremiseProviderAddressVersions] AS [t2]
       ON [t1].[premiseprovideraddressId] = [t2].[premiseprovideraddressId]
    WHERE [t0].[postcode] = @p1 AND 
          [t1].[premiseproviderId] = [t0].[premiseproviderId]
    )

For readability you can extract subquery definition into separate variable:

var providerIds = 
       from a in db.PremiseProvideAddresses
       join v in db.PremiseProviderAddressVersions
           on a.premiseprovideraddressId equals v.premiseprovideraddressId
       where v.postcode == "84280"
       select a.premiseproviderId;

var providers = from p in db.PremiseProviders
                where providerIds.Contains(p.premiseProviderId)
                select p;

NOTE: If instead of subquery you will pass result of query execution (i.e. save ids to list or array, then IN operator will be generated just as in first sample in my answer).

OTHER TIPS

First get all the premiseProviderId results for given postcode. Then filter the providers that have an PermiseProviderId that exists in the former result:

var providersIDs = (from a in dbo.PremiseProviderAddresses
                    join v in dbo.premiseProviderAddressVersions
                    on a.premiseprovideraddressId equals v.premiseprovideraddressId
                    where v.postcode == "84280"
                    select a.premiseproviderId).ToList();

var result = dbo.PremiseProviders.Where(x => providersIDs.Contains(x.PremiseProviderId));

First you select the premiseProviderIds for postcode = 84280 (lets call it premiseProviderIdsForPostcode84280.

Then you do something like:

var query = from p in dbo.PremiseProviders
                   where premiseProviderIdsForPostcode84280.Contains(p.premiseProviderId)
                   select p;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top