1

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.

3
  • Where did the property owner.Name came from ? Commented May 15, 2019 at 12:02
  • It would be better to rearrange the data to a data structure like Lookup, which would make your querying many time faster, your current query has the time complexity of O(N^2), which is killing performance for lots of data, and for 1000 records complexity becomes 1 million iterations Commented May 15, 2019 at 12:48
  • In actual Query version, you are using a Join, then why would you not Join in the Lambda query, it is bound to have an impact Commented May 16, 2019 at 11:31

3 Answers 3

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

This is the correct replacement of the OP's query version
0

I think you can use this one:

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

Comments

0

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.

2 Comments

You re forgetting join by LandId
That relation should be taken care of by Entity Framework itself. The relationship can be defined using convention, like in the example above, or explicit using Fluent API.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.