How to include only some items of internal list with LINQ to Entities

c# entity-framework linq

Question

I have following entities (simplified for readability):

public class Country
{
    public List<NameLocalized> Names;
}

public class NameLocalized
{
    public string Locale;
    public string Value;
}

I also have a DbSet<Country> Countries in my context. How to write a LINQ query which will return the list of countries but with filtered Names (so Names list will contain only single item based on specified locale. Something like this (however, this is not a working example)

public List<Country> GetCountries(string locale)
{
    var result = context.Countries.Include(c => c.Names.Select(n => n.Locale == locale)).ToList();
    return result;
}

How to achieve this in 2 steps if not possible in one

public List<Country> GetCountries(string locale)
{
    //I have to use Include for eager loading
    var tempResult = context.Countries.Include(c => c.Names);

    var result = //Some code to convert tempResult to result, where only interesting locale is included
    return result;
}

I am trying following code to remove unnecessary items, but it does not work too

result.ForEach(c => c.Names.ToList().RemoveAll(n => n.Locale != locale)); 

UPDATE: I have managed to remove items with following code (using extension method)

public static void RemoveAll<T>(this ICollection<T> collection,Predicate<T> predicate) 
{
    if (predicate == null)
    {
        throw new ArgumentNullException("predicate");
    }
     collection.Where(entity => predicate(entity))
        .ToList().ForEach(entity => collection.Remove(entity));
}


result.ForEach(c => c.Names.RemoveAll(n => n.Locale != locale));

UPDATE2:

With the help of answers and comments I was able to succeed. Details are at Convert Entity with navigation property to DTO using IQueryable

1
3
5/23/2017 10:28:28 AM

Popular Answer

Since your model defines Country as something that has multiple Names, it may be confusing to have a Country instance that only has one of its Names. Instead, create a separate type to represent the concept of the information that is known about a Country for a given locale.

public class LocaleCountry
{
    public int CountryId {get;set;}
    public string Name {get;set;}
    public string Locale {get;set;}
}


public List<LocaleCountry> GetCountries(string locale)
{
    var result = context.Countries
        .Select(c => new LocaleCountry
        {
            CountryId = c.Id,
            Name = c.Names
               .Where(n => n.Locale == locale)
               .Select(n => n.Name)),
            Locale = locale
        })
        .ToList();
    return result;
}
1
3/28/2016 8:29:18 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow