Sebastian Muntean
Sebastian Muntean

Reputation: 9

Filter list of entity objects by string child object property using Linq Lambda

I am trying to return an IQueryable lands filtered by a child object property Owner.Name. Is working well with the query style solution, but I want to use a lambda one.

On short these are my classes mapped by EntityFramework:

public class Land
{
     public int Id { get; set; }

     public virtual ICollection<Owner> Owners { get; set; }
}

public class Owner
{
        public int Id { get; set; }
        public string Name { get; set; }
        public int LandId { get; set; }

        public virtual Land Lands { get; set; }
}

The query which is working fine:

 var list = from land in db.Lands
                   join owner in db.Owners on land.Id equals Owner.LandId
                   where owner.Name.Contains("Smit")
                   select land;

I was trying using this:

var list = db.Lands.Where(lnd => lnd.Owners.Count() > 0 &&
             lnd.Owners.Where(own => own.Name.Contains("Smit")).Count() > 0);

It works only for small lists, but for some with thousands of records it gives timeout.

Upvotes: 1

Views: 945

Answers (3)

Jacek Glen
Jacek Glen

Reputation: 1546

Try something more straightforward:

var lands = db.Owners.Where(o => o.Name.Contains("Smit")).Select(o => o.Lands);

You just need to make sure that Owner.Name is not null and LINQ will do the rest.

Upvotes: 0

Gibbon
Gibbon

Reputation: 2773

Well, one issue which may be causing the speed problem is that your lambda version and your non-lambda versions do very different things. You're non lambda is doing a join with a where on one side of the join.

Why not just write the lambda equivalent of it?

var list = db.Lands.Join(db.Owners.Where(x=> x.Name.Contains("Smit")), a=> a.Id, b => b.LandId, (a,b) => a).toList();

I mean, that is the more direct equivalent of your non lambda

Upvotes: 2

hassan.ef
hassan.ef

Reputation: 1350

I think you can use this one:

var list = db.Lands.Where(lnd => lnd.Owners.Any(x => x.Name.Contains("Smit")));

Upvotes: 0

Related Questions