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