Question

The Linq-to-SQL query below, currently results in:

NotSupportedException: Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.

Looks like the typical way to perform an exact relational division filter in linq is not available when using linq to SQL.

In the query below, we see the two attempts to use the Except clause to filter out any records that do not have IDs in the provided range.

Does anyone know what needs to be done besides changing to using a stored procedure or deferring the Expect filter to further filter on the returned list?

The section specifically is

&&
(additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||  
    !(AdditionalServices.Where(ads => p.ReferenceNumber == ads.FK_Provider_ReferenceNumber).Select(ad => ad.FK_ServiceList_ID).Except(additionalServiceIDs).Any())
) //  *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)
&&
(additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||  
    !(AdditionalNeeds.Where(adn => p.ReferenceNumber == adn.FK_Provider_ReferenceNumber).Select(an => an.FK_ServiceList_ID).Except(additionalNeedsIDs).Any())
) //  *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)

in :

List<int> additionalServiceIDs = new List<int>(){40,42}; 
List<int> establishmentIDs = new List<int>() {}; 
List<int> additionalNeedsIDs = new List<int>(){}; 
bool advertisedOnly = true; 
bool Internal = true;
string providerTypeCode = "";
List<string> settingTowns = new List<string>() {};

var sqlResultsList = (from p in Providers
                          join po in ProviderOverviews on p.ReferenceNumber equals po.FK_Provider_ReferenceNumber into p_po
                          from p_po_LeftOuter in p_po.DefaultIfEmpty() // left outer join
                          join ad in AdditionalServices on p.ReferenceNumber equals ad.FK_Provider_ReferenceNumber into p_ad
                          from p_ad_LeftOuter in p_ad.DefaultIfEmpty() // left outer join
                          join sp in SchoolPickUps on p.ReferenceNumber equals sp.FK_Provider_ReferenceNumber into p_sp
                          from p_sp_LeftOuter in p_sp.DefaultIfEmpty() // left outer join
                          join an in AdditionalNeeds on p.ReferenceNumber equals an.FK_Provider_ReferenceNumber into p_an
                          from p_an_LeftOuter in p_an.DefaultIfEmpty() // left outer join
                          join il in Inspections on p.ReferenceNumber equals il.FK_Provider_ReferenceNumber into p_il
                          from p_il_LeftOuter in p_il.DefaultIfEmpty() // left outer join

                          join sl in SchoolLists on p_sp_LeftOuter.FK_SchoolList_SchoolID equals sl.SchoolID into sp_sl
                          from sp_sl_LeftOuter in sp_sl.DefaultIfEmpty() // left outer join

                          join nl in NeedLists on p_an_LeftOuter.FK_NeedsList_ID equals nl.ID into an_nl
                          from an_nl_LeftOuter in an_nl.DefaultIfEmpty() // left outer join

                          join svl in ServiceLists on p_ad_LeftOuter.FK_ServiceList_ID equals svl.ID into ad_svl
                          from ad_svl_LeftOuter in ad_svl.DefaultIfEmpty() // left outer join

                          join ptl in ProviderTypeLists on p.FK_ProviderTypeList_ID equals ptl.ID 

                          where

                                        (string.IsNullOrEmpty(providerTypeCode) || ptl.Code.ToLower() == providerTypeCode)
                                        &&
                                        p.Advertise == advertisedOnly
                                        &&
                                        (settingTowns == null || settingTowns.Count == 0 || settingTowns.Contains(p.SettingTown.ToLower())) // allow for no parameters being passed
                                        &&
                                        (establishmentIDs == null || establishmentIDs.Count == 0 || establishmentIDs.Contains(p_sp_LeftOuter.FK_SchoolList_SchoolID)) // allow for no parameters being passed
                                        &&
                                        (Internal == true || p.RegistrationStatus == "ACTV")// if internal = false then add filter ..  RegistrationStatus =  'ACTV'
                                        &&
                                        (additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||  
                                            !(AdditionalServices.Where(ads => p.ReferenceNumber == ads.FK_Provider_ReferenceNumber).Select(ad => ad.FK_ServiceList_ID).Except(additionalServiceIDs).Any())
                                        ) //  *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)
                                        &&
                                        (additionalNeedsIDs== null || additionalNeedsIDs.Count == 0 ||  
                                            !(AdditionalNeeds.Where(adn => p.ReferenceNumber == adn.FK_Provider_ReferenceNumber).Select(an => an.FK_NeedsList_ID).Except(additionalNeedsIDs).Any())
                                        ) //  *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)

                  select new // anonymous type
                                  {
                                      SettingTown = p.SettingTown,
                                      ProviderTypeCode = ptl.Code,
                                      ProviderName = p.ProviderName,
                                      PublishedAddress = p_po_LeftOuter.PublishedAddressLocation,
                                      Vacancies = p_po_LeftOuter.Vacancies,
                                      VacancyMemo = p_po_LeftOuter.VacancyMemo,
                                      PublishedPhone = p_po_LeftOuter.PublicPhone,
                                      PublishedEmail = p_po_LeftOuter.PublicEmail,
                                      Website = p_po_LeftOuter.Website,
                                      AdditionalNeed = an_nl_LeftOuter.Description,
                                          AdditionalNeedID = (int?)an_nl_LeftOuter.ID,
                                          AdditionalService = ad_svl_LeftOuter.Description,
                                          AdditionalServiceID = (int?)ad_svl_LeftOuter.ID,
                                      CostPerDay = p_po_LeftOuter.CostPerDay,
                                      CostPerHour = p_po_LeftOuter.CostPerHour,
                                      CostPerSession = p_po_LeftOuter.CostPerSession,
                                      Hours = p_po_LeftOuter.Hours,
                                      InspectionOverallJudgement = p_il_LeftOuter.InspectionOVerallJudgement,
                                      ReferenceNumber = p.ReferenceNumber,
                                      ServiceDescription = p_po_LeftOuter.ServiceDescription,
                                      SchoolPickUp = sp_sl_LeftOuter.SchoolName,
                                      Under5 = p_po_LeftOuter.Under5,
                                      Over5 = p_po_LeftOuter.Over5,
                                      PublicTransport = p_po_LeftOuter.PublicTransport,
                                       }).ToList();
Was it helpful?

Solution

The error message suggests that you can't use local sequence in LINQ to SQL except Contains() function. Based on that suggestion, try to avoid using .Except() and use .Contains() instead. You can replace this :

.Except(localCollection) 

with this one :

.Where(!localCollection.Contains())

Example for your case :

(additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||  
    !(AdditionalNeeds.Where(adn => p.ReferenceNumber == adn.FK_Provider_ReferenceNumber)
                     .Select(an => an.FK_ServiceList_ID)
                     .Where(fk => !additionalNeedsIDs.Contains(fk))
                     .Any())
) //  *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)

or simplified by merging both .Where()s :

(additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||  
    !(AdditionalNeeds.Where(adn => p.ReferenceNumber == adn.FK_Provider_ReferenceNumber 
                                    && !additionalNeedsIDs.Contains(adn.FK_ServiceList_ID))
                     .Select(an => an.FK_ServiceList_ID)
                     .Any())
) //  *ONLY* records that match the provided list of additionalServiceIDs, no more - no less (aka. Exact Relational Division)

OTHER TIPS

With help from @har07 I figured it out in entirety, the filter is thus.

&&
    (additionalServiceIDs == null || additionalServiceIDs.Count == 0 ||
        !(dbo.AdditionalServices.Where(ads => p_ad_LeftOuter.FK_Provider_ReferenceNumber == ads.FK_Provider_ReferenceNumber
                                    && !additionalServiceIDs.Contains(ads.FK_ServiceList_ID)
                                    )
                                    .Select(an => an.FK_ServiceList_ID)
                                    .Any())

        &&
        p_ad_LeftOuter.FK_ServiceList_ID != null
        &&
        dbo.AdditionalServices.Where(ads => p_ad_LeftOuter.FK_Provider_ReferenceNumber == ads.FK_Provider_ReferenceNumber
                                        && additionalServiceIDs.Contains(ads.FK_ServiceList_ID))
                              .Select(an => an.FK_ServiceList_ID)
                              .Distinct()
                              .Count() == additionalServiceIDs.Count
    )
&&
    (additionalNeedsIDs == null || additionalNeedsIDs.Count == 0 ||
        !(dbo.AdditionalNeeds.Where(ads => p_an_LeftOuter.FK_Provider_ReferenceNumber == ads.FK_Provider_ReferenceNumber
                                    && !additionalNeedsIDs.Contains(ads.FK_NeedsList_ID)
                                    )
                                    .Select(an => an.FK_NeedsList_ID)
                                    .Any())

        &&
        p_an_LeftOuter.FK_NeedsList_ID != null
        &&
        dbo.AdditionalNeeds.Where(ads => p_an_LeftOuter.FK_Provider_ReferenceNumber == ads.FK_Provider_ReferenceNumber
                                        && additionalNeedsIDs.Contains(ads.FK_NeedsList_ID))
                              .Select(an => an.FK_NeedsList_ID)
                              .Distinct()
                              .Count() == additionalNeedsIDs.Count
    ) 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top