Vadym Pavliuk
Vadym Pavliuk

Reputation: 35

LINQ to SQL filter child collection

I'm strugling with this query, i think I'm missing something. I have two autogenerated dbml models.

    public partial class RegulatorsOrganizationView
    {
        private int regulatorOrgId;
        private string regulatorOrgName;
        private EntitySet<RegulatorsView> regulatorsViews;
    }

    public partial class RegulatorsView
    {
        private int regulatorId;
        private string regulatorName;
    }

Currently I'm loading all the matching regualatorsOrganizationViews, and do filtering on regulators down the line.

List<RegulatorOrganizationView> regOrgs = boatDataContext.RegulatorOrganizationView
                .Where(r => r.RegulatorsViews.Any(ar => ar.regulatorName.ToUpper().Contains(filterText.ToUpper()))
                || r.regulatorName.ToUpper().Contains(filterText.ToUpper())
                .ToList();

         

But this way I'm loading redundent Regulators only to filter them out later on. How can I rebuild this query to load only matching regulators from starters ?

It tried to use Select() to assign regulatorOrgnization filter list of Regulators.

            regulatorsOrgs = DataContext.RegulatorOrganizationViews
            .Where(ro => ro.regulatorOrgName.ToUpper().Contains(filterText.ToUpper())
            || ro.RegulatorsViews.Any(r => r.regulatorName.ToUpper().Contains(filterText.ToUpper()))
            .Select(ro => new RegulatorOrganizationView()
            {
                regulatorId = ro.regulatorId,
                regulatorOrgName = ro.regulatorOrgName,

                RegulatorsViews = ro.RegulatorsViews
                         .Where(r => r.regulatorName.ToUpper().Contains(filterText.ToUpper())
                         .Select(r => new RegulatorsView()
                         {
                             regulatorId = r.regulatorId,
                             regulatorName = r.regulatorName,
                         }).ToEntitySet()
            
            }).ToList();

But I'm getting exception: Message="The explicit construction of the entity type 'RegulatorsOrganizationView' in a query is not allowed."

Looks like filtered Include() would be an option (like in EF) but I can't find a way to use it with Linq To SQL. Any ideas ?

Upvotes: 0

Views: 83

Answers (1)

Gert Arnold
Gert Arnold

Reputation: 109185

In LINQ-to-SQL it's a bit messy and not intuitive to do this. You have to use DataLoadOptions:

var opt = new DataLoadOptions();

opt.AssociateWith((RegulatorsOrganizationView v) 
    => v.regulatorsViews.Where(ar => ar.regulatorName.Contains(filterText)));

opt.LoadWith((RegulatorsOrganizationView v) => => v.regulatorsViews);

DataContext.LoadOptions = opt;

var result = DataContext.RegulatorOrganizationViews
            .Where(ro => ro.regulatorOrgName.Contains(filterText) 
                      && ro.regulatorsViews.Any());

So this says: when loading RegulatorOrganizationViews, then when their regulatorsViews are associated, make them meet the given condition.

Then it says: when when loading RegulatorOrganizationViews, also load their regulatorsViews.

The latter is like Include in Entity Framework. The former makes it behave like filtered Include, or maybe closer, a global query filter.

I removed the ToUpper calls for brevity, but you don't need them if the database collation is case-insensitive.

Upvotes: 1

Related Questions