简体   繁体   中英

Multiple Include and Where Clauses Linq

I have a database where I'm wanting to return a list of Clients.

These clients have a list of FamilyNames.

I started with this

var query = DbContext.Clients.Include(c => c.FamilyNames).ToList() //returns all clients, including their FamilyNames...Great.

But I want somebody to be able to search for a FamilyName, ifany results are returned, then show the clients to the user.

so I did this...

var query = DbContext.Clients.Include(c => c.FamilyNames.Where(fn => fn.familyName == textEnteredByUser)).ToList();

I tried...

var query = DbContext.Clients.Include(c => c.FamilyNames.Any(fn => fn.familyName == textEnteredByUser)).ToList();

and...

var query = DbContext.FamilyNames.Include(c => c.Clients).where(fn => fn.familyname == textEnteredByUser.Select(c => c.Clients)).ToList();

What I would like to know (obviously!) is how I could get this to work, but I would like it if at all possible to be done in one query to the database. Even if somebody can point me in the correct direction.

Kind regards

In Linq to Entities you can navigate on properties and they will be transformed to join statements.

This will return a list of clients.

var query = DbContext.Clients.Where(c => c.FamilyNames.Any(fn => fn == textEnteredByUser)).ToList();

If you want to include all their family names with eager loading, this should work:

var query = DbContext.Clients.Where(c => c.FamilyNames.Any(fn => fn == textEnteredByUser)).Include(c => c.FamilyNames).ToList();

Here is some reference about loading related entities if something doesn't work as expected.

You can use 'Projection', basically you select just the fields you want from any level into a new object, possibly anonymous.

var query = DbContext.Clients
    .Where(c => c.FamilyNames.Any(fn => fn == textEnteredByUser))
    // only calls that can be converted to SQL safely here
    .Select(c => new {
        ClientName = c.Name,
        FamilyNames = c.FamilyNames
    })
    // force the query to be materialized so we can safely do other transforms
    .ToList()
    // convert the anon class to what we need
    .Select(anon => new ClientViewModel() {
        ClientName = anon.ClientName,
        // convert IEnumerable<string> to List<string>
        FamilyNames = anon.FamilyNames.ToList()
    });

That creates an anonymous class with just those two properties, then forces the query to run, then performs a 2nd projection into a ViewModel class.

Usually I would be selecting into a ViewModel for passing to the UI, limiting it to just the bare minimum number of fields that the UI needs. Your needs may vary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM