Dronacharya
Dronacharya

Reputation: 1281

Two lambda expressions in a single query

I have a list of products and I have included ProductMetadatas in the query like this:

var products = _dbContext.Set<Product>()Include(x=>x.Productmetadatas).
    Where(x => x.CompanyId == LoggedInUser.CompanyId && x.Active).ToList();

Now, what I want to do is I want to filter the ProductMetadats according to the CompanyId, like

var products = _dbContext.Set<Product>()Include(x=>x.Productmetadatas).
     Where(x => x.CompanyId == LoggedInUser.CompanyId && x.Active && 
           x.ProductMetadatas.Where(pm => pm.CompanyId == LoggedInUser.CompanyId)).ToList();

How can I do it in a single query?

Upvotes: 0

Views: 95

Answers (2)

Khalydor
Khalydor

Reputation: 21

If you want all products that actually do match your current users companyId you have to change it to the following:

var products = _dbContext.Set<Product>()Include(x=>x.Productmetadatas).
 Where(x => x.CompanyId == LoggedInUser.CompanyId && x.Active && 
       x.ProductMetadatas.Any(pm => pm.CompanyId == LoggedInUser.CompanyId)).ToList();

As you can guess .Any() checks if any element in your list matches your LINQ expression and returns a boolean. With that your expression is valid.

Previously it could not work because .Where() returns a list of elements.

EDIT:

Alright as it was noted that you want to adjust the ProductMetdatas you can do the following:

Create an extension for IEnumerable<T>:

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach(T item in source)
        action(item);
}

And then adjust your LINQ like this:

var products = _dbContext.Set<Product>()Include(x=>x.Productmetadatas).
     Where(x => x.CompanyId == LoggedInUser.CompanyId && x.Active).
     ForEach(x => x.ProductMetadatas = x.ProductMetadatas.
     Where(pm => pm.CompanyId == LoggedInUser.CompanyId).ToList()).ToList();

Now you invoke a function on each element which filters the ProductMetadatas and sets the property of your product to the filtered ProductMetadatas.

Upvotes: 2

summerGhost
summerGhost

Reputation: 497

You can use join to filter.

    var result = (from tbl in _dbContext.Set<Product>()
                  join lst in ProductMetadatas on lst.CompanyID eqauls LogginInUSer.CompanyID
                  where tbl.CompanyId == LoggedInUser.CompanyId && tbl.Active
select tbl)

Upvotes: 0

Related Questions