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
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;
}