Linq Table select where IN IQueryable - linq

I have two classes; the first one is:
public class People
{
public int Id {get;set;}
public Dog Dogs {get;set;}
}
public class Dog
{
public int Id {get;set;}
public string Name {get; set;}
public int PeopleId {get;set;}
public bool IsNewborn {get;set;}
}
PeopleId of Dog class is the Id of People class.
Now, with Entity Framework, I retrive the list of Newborn Dogs:
var AllNB_dogs = _dog_repository.Table;
AllNB_dogs = AllNB_dogs.Where(x => x.IsNewborn );
What I need to retrive now, is the list of People that have newborn dogs.
I try with:
var PeopleWithNB = _people_repository.Table.Where(x => AllNB_dogs.Contains(x.Id));
but I know that in "Contains" I cannot put an Int but I need to insert a People object.
I try also with:
var PeopleWithNB = _people_repository.Table.Select(x => ...);
but without success.
Can someone help me? Or there is another way to accomplish this?
I'm using EF Core 2.2.

Assuming you have a relation between People and Dogs, so that you can use Any:
var PeopleWithNB = _people_repository.Table.Where(x => x.Dogs.Any(d => d.IsNewborn)).ToList();
See Relationships in Entity-Framework Core

According to your design every human has exactly one Dog, there are no People without dogs (I'm sure there are a lot of people without dogs), nor people with more than one Dog. I wonder what you would do if someone sells his Dog.
Furthermore, People have a property Dogs, it seems that you wanted to design a one-to-many relationship between People and Dogs. Every Human has zero or more Dogs, every Dog belongs to exactly one Human, namely the Human with PeopleId.
If you really wanted a one-to-one relationship (every Human has exactly one Dog), see below. I'll first handle the one-to-many relation.
One To Many
People have zero or more Dogs, every Dog belongs to exactly one Human, namely the Dog that PeopleId refers to.
Usually tables are identified with plural nouns, rows in tables are identified with singular nouns. Because the word People has some problems when explaining, I'll change it to something more standard. For your final solution the identifiers that you select are not important. Most important is that everybody immediately understands what you mean.
Rewriting your classes:
public class Customer
{
public int Id {get;set;}
public string Name {get; set;}
... // other Customer properties
// every Customer has zero or more Dogs (one-to-many)
public virtual ICollection<Dog> Dogs {get;set;}
}
public class Dog
{
public int Id {get;set;}
public string Name {get; set;}
public bool IsNewborn {get;set;}
... // Other Dog properties
// Every Dog is owned by exactly one Customer, the Customer that OwnerId refers to
public int OwnerId {get;set;}
public virtual Customer Owner {get; set;}
}
In Entity framework, the columns of the tables are represented by the non-virtual properties, the virtual properties represent the relations between the tables (one-to-many, one-to-one, many-to-many, ...)
Note that a foreign key is an actual column in your table, hence it is a non-virtual property.
The -to-many part is best represented by a Collection<...>, not by a IList<...>. The reason for this is that all functionality of a Collection is supported by Entity Framework: Add / Remove / Count. An IList has functionality that is not supported by entity framework, better not offer it then, don't you agree?
For completeness the DbContext:
class MyDbContext : DbContext
{
public DbSet<Customer> Customers {get; set; }
public DbSet<Dog> Dogs {get; set;}
}
Most people directly access the DbContext. It seems you have a repository class. Alas you forgot to mention this class. Anyway, you have functions like:
IQueryable<Customer> Customers = ... // query all Customers
IQueryable<Dog> Dogs = ... // query all Dogs
** Back to your question **
Ok, so you have a query to fetch the sequence of several Dogs (in this case: all new born Dogs) and you want the list of Customers that own these Dogs.
If you use entity framework with proper virtual relations, this is quite easy:
// Get all owners of New Born Dogs:
var result = dogs.Where(dog => dog.IsNewBorn)
.Select(dog => new
{
// Select only the Dog properties that you plan to use:
Id = dog.Id,
Name = dog.Name,
...
Owner = new
{
// Select only the properties that you plan to use:
Id = dog.Owner.Id,
Name = dog.Owner.Name,
...
}),
});
In words: from the sequence of Dogs, keep only the newborn dogs. From every remaining Dog, select properties Id, Name. From the Owner of this Dog, select properties Id and Name.
You see: by using proper plural and singular nouns, and by using the virtual relations, the query seems to be very natural.
The problem with this is that, if Customer[4] has two new born dogs, you get this Customer twice. It would be better to query:
Give me all Customers with their newborn Dogs.
Whenever you have a one-to-many relationship, like Customers with their Dogs, Schools with their Students, Orders with their Products, so whenever you want items with their sub-items, it is best to start at the one side (Customers) and use a GroupJoin.
var customersWithTheirNewbornDogs = customers.Select(customer => new
{
// Select only the Customer properties that you plan to use
Id = customer.Id,
...
NewbornDogs = customer.Dogs.Where(dog => dog.IsNewborn)
.Select(dog => new
{
Id = dog.Id,
...
// not needed, you already know the value:
// OwnerId = dog.OwnerId,
})
.ToList(),
})
// Result: all Customers, each with their newborn Dogs,
// even if the Customer has no newborn Dogs.
// if you only want Customers that have newborn Dogs:
.Where(customer => customer.NewbornDogs.Any());
In words: from every Customer take some properties, and from all Dogs that he owns, keep only the newborn ones. From the remaining ones, take some properties. Finally, keep only Customers that have at least one newborn Dog.
** but I'm using entity framework CORE! **
I've heard from some people who can't use the virtual properties when using EF-core. In that case, you'll have to join the tables yourself:
Starting on the many side: GroupJoin:
// GroupJoin Customers and newbornDogs
var customersWithTheirNewbornDogs = customers
.GroupJoin(dogs.Select(dog => dog.IsNewborn),
customer => customer.Id, // from every Customer take the Id
dog => dog.OwnerId, // from every Dog take the foreign key
(customer, dogsOfThisCustomer) => new // when they match, take the customer and his Dogs
{ // to make one new object
Id = customer.Id,
...
NewBornDogs = dogsOfThisCustomer.Select(dog => new
{
Id = dog.Id,
...
});
});
Or if you want to start on the many side: Join
var newbornDogsWithTheirOwners = dogs.Where(dog => dog.IsNewborn)
.Join(customers,
dog => dog.OwnerId, // from every Dog take the OwnerId,
customer => customer.Id, // from every Customer take the Id,
(dog, owner) => new // when they match, take the dog and the owner
{ // to make one new
Id = dog.Id,
...
Owner = new
{
Id = owner.Id,
...
}
});
One-to-One
If in your world every People has exactly one Dog, there are no People without Dogs, and no one has several Dogs, than you can do the Join similar as above.
(by the way, see how strange it sounds if you don't use proper plurals and singular nouns?)
var newbornDogsWithTheirOwners = dogs.Where(dog => dog.IsNewborn)
.Join(People,
dog => dog.PeopleId, // from every Dog take the foreign key,
customer => customer.Id, // from every Customer take the Id,
(dog, owner) => new // when they match, take the dog and the owner
{ // to make one new
Id = dog.Id,
...
Owner = new
{
Id = owner.Id,
...
}
});

Related

Returning a list inside Linq query from left outer join

I'm new with Linq and hoping for some clarity on a particular query.
I have two tables (simplified for demonstration):
Table: Customer
CustomerId | Name
1 | John Smith
2 | Peter James
Table: Order
id | CustomerId | Total
1 | 1 | $100
2 | 1 | $200
Sample CustomerDto:
public class CustomerDto
{
public long CustomerId { get; set; }
public string Name{ get; set; }
public CustomerOrder[] CustomerOrderList{ get;set;}
}
Linq example for left outer join in the select here, they return string.empty if the join fails, I'm not sure the equivalent when I'm returning an object rather than a string.
My Linq query looks as follows. I've used the DefaultIfEmpty() to assist in a left outer join, however given I'm dealing with my object, I'm not sure how to return null if there isn't anything.
IQueryable<CustomerDto> search =
from customer in _database.Customer
join customerOrder in _database.CustomerOrder on customer.CustomerId equals customerOrder.CustomerId into CS
from subCustomerSale in CS.DefaultIfEmpty()
select new CustomerDto
{
CustomerId = customer.CustomerId,
Name = customer.Name,
CustomerOrderList = subCustomerSale
};
As I mentioned, I want to return a list of orders rather than one row per order. So there should be two records returned (the two customers), one with a list of orders and the other without any.
How do I achieve this?
The first step to make the entities easier to work with is to ensure that navigation properties are set up. If the table is called "Order" then the entity can be Order, or renamed to CustomerOrder if you like. A Customer entity can have an ICollection<Order> collection which EF can automatically map provided a consistent naming convention and normalization is used. (Otherwise explicit mapping can be provided)
For example:
public class Customer
{
[Key]
public int CustomerId { get; set; }
// other customer fields.
public virtual ICollection<Order> Orders { get; set; } = new List<Order>();
}
From here you are projecting Customers to a CustomerDTO, so we should also project the Orders to an OrderDTO. Note that when using navigation properties we don't have to explicitly join entities. We don't even have to eager load related data via Include(). The later would apply if/when we want to work with the entities rather than projections.
The resulting query would end up looking like:
IQueryable<CustomerDto> search = _database.Customer
.Select(c => new CustomerDto
{
CustomerId = c.CustomerId,
Name = c.Name,
Orders = c.Orders.Select(o => new OrderDto
{
OrderId = o.OrderId,
Total = o.Total
}).ToList()
});
The benefit is no need to explicitly write Join expressions. EF can help simplify accessing related data considerably rather than just facilitating using Linq as an alternative to SQL. This would return an empty list rather than #null if there are no Orders for that customer. It may be possible to substitute a #null if there aren't any orders, though worst case it could be post-processed after the results are materialized Ie:
var customers = await search.ToListAsync();
var noOrderCustomers = customers.Where(c => !c.Orders.Any()).ToList();
foreach(var customer in noOrderCustomers)
customer.Orders = null;
It really just boils down to whether the consumer is Ok knowing there is always an Orders collection that will be empty if there are no orders, or in the Orders collection is only present if there are orders. (via JSON etc. serialization)
The important details to consider: When filtering, such as filling in search criteria, do this before the Select as the IQueryable is working with entities so you have full access to the table fields. Adding Where clauses after the Select will limit the available fields to the ones you have selected for the DTO. (They will still bubble down into the SQL) There is a ToList inside the Select to build the Orders collection. This may look "bad" that it might be materializing data synchronously, but it will be executed only when the main query is. (Such as an awaited async operation on the IQueryable)
When projecting to DTOs be sure not to mix DTOs and entities such as:
IQueryable<CustomerDto> search = _database.Customer
.Select(c => new CustomerDto
{
CustomerId = c.CustomerId,
Name = c.Name,
Orders = c.Orders
});
... which can be tempting. The issue here is that "c.Orders" would return a collection of Order entities. Those Orders may have references to other entities or information you don't need to/want to expose to the consumer. Accessing references could result in lazy load costs, null references, or exceptions (i.e. disposed DbContext) depending on when/where they occur.
just put the ternary condition to achieve it like follows:
IQueryable<CustomerDto> search =
from customer in _database.Customer
join customerOrder in _database.CustomerOrder on customer.CustomerId equals customerOrder.CustomerId into CS
from subCustomerSale in CS.DefaultIfEmpty()
select new CustomerDto
{
CustomerId = customer.CustomerId,
Name = customer.Name,
CustomerOrderList = subCustomerSale == null ? null : subCustomerSale // add this line and you will get the null as well if there is no record
};

are we able to Include(x=>x.Entity) then Select(x=> new Entity{ A=x.A })

I'm trying to call my CompanyCatalog table with its FileRepo table. There is a One to One relationship between them and i wanna apply when i Include(x=>x.FileRepo.Select(a=> new{ FileName=a.FileNAme} )) or any query like that.
Let me show to you my query in the bellow :
return TradeTurkDBContext.CompanyCatalog.Include(x=>x.FileRepo
.Select(x=> new FileRepo(FileName=x.FileName))).AsNoTracking().ToList();
I'm trying to do something like that. I'm asking is it possible or not ? if it's possible then how ?
So you have a table of CompanyCatalogs and a table of FileRepos. Every CompanyCatalog has exactly one FileRepo (one-to-one), namely the one that the foreign key refers to.
If you've followed the entity framework conventions, you will have classes similar to the following:
class CompanyCatalog
{
public int Id {get; set;}
public string Name {get; set;}
... // other properties
// every CompanyCatalog has one FileRepo, the one that the foreign key refers to
public int FileRepoId {get; set;}
public virtual FileRepo FileRepo {get; set;}
}
class FileRepo
{
public int Id {get; set;}
public string Name {get; set;}
... // other properties
// every FileRepo is the FileRepo of exactly one CompanyCatalog
// namely the one that the foreign key refers to
public int CompanyCatalogId {get; set;}
public virtual CompanyCatalog CompanyCatalog {get; set;}
}
This is enough for entity framework to detect your tables, the columns in the tables and the relations between the tables. If you had a one-to-many, you would have had a virtual ICollectioni<...> on the "one side". Only if you deviate from the conventions, for instance because you want other table names, or other column names, you need attributes or fluent API.
In entity framework the columns are represented by non-virtual properties. The virtual properties represent the relations between the tables (one-to-many, many-to-many, etc)
Foreign keys are columns in a table, hence they are not virtual. FileRepo is no column in the CompanyCatalogs table, hence it is declared virtual.
You want several properties of CompanyCatalogs, each with several properties of their FileRepos. You use Include for this. This is not necessary. A simple Select will do.
var companyCatalogs = dbContext.CompanyCatalogs
.Where(catalog => ...) // only if you don't want all CompanyCatalogs
.Select(companyCatalog => new
{
// Select only the CompanyCatalog properties that you plan to use:
Id = companyCatalog.Id,
Name = companyCatalog.Name,
...
// Select the FileRepo of this CompanyCatalog as one sub object
FileRepo = new
{
Date = companyCatalog.FileRepo.Date,
Title = companyCatalog.FileRepo.Title,
...
},
// if you want you can select the FileRepo properties one by one:
FileRepoDate = companyCatalog.FileRepo.Date,
FileRepoTitle = companyCatalog.FileRepo.Title,
});
Entity Framework knows your relations, and because you used the virtual properties of the class, it knows it has to perform a (Group-)Join.

All items that match all the words in a collection

I have two lists: a list of type Person and a list of type profession. Both are many-to-many related.
In addition, I have a third list with some professions.
I would like to select all persons that match all the professions in the third list.
What would be LINQ/Lambda expression?
Thanks
The answer depends on how your sequence of Persons are connected to your sequence of Professions.
You are talking about Lists, but also about many-to-many relation, so I assume your lists are in fact tables in a relational database, with a joining table that remembers which Persons and Professions are related.
If you use entity framework, and you have set-up the many-to-many relationship correctly you don't need the third table:
class Person
{
public int Id {get; set;}
... // other properties
// every Person has zero or more Professions (many-to-many)
public virtual ICollection<Profession> Professions {get; set;}
}
class Profession
{
public int Id {get; set;}
... // other properties
// every Profession has zero or more Persons (many-to-many)
public virtual ICollection<Person> Persons {get; set;}
}
class MyDbContext : DbContext
{
public DbSet<Person> Persons {get; set;}
public DbSet<Profession> Professions {get; set;}
}
That is all!
Entity Framework will recognize that you are modeling a many-to-many relationship and will create the third table for it. You don't need this third table, just access the ICollections, and entity framework will automatically perform the required joins with the third table.
using (var dbContext = new MyDbContext())
{
IEnumerable<Profession> professionList = ... // the third list
// Keep only the persons where have exactly all Professions from the profession list
// do this by checking the Ids of the professions in the list
IEnumerable<int> professionIds = professions
.Select(profession => profession.Id)
.OrderBy(id => id);
var personsWithProfessions = dbContext.Persons
// keep only persons that have the same Profession Ids as professionIds
// first extract the the profession Ids the person has
.Where(person => person.Professions
.Select(profession => profession.Id)
// order this in ascending order
.OrderBy(id => id)
// check if equal to professionIds:
.SequenceEqual(professionIds))
If you are not using Entity Framework, or the classes are not set-up properly with the virtual ICollection, you'll have to do the join between Persons and Professions yourself
Assuming you have a joining table that joins your Persons and Professions:
class Person_Profession
{
public int Id {get; set;}
public int PersonId {get; set;}
public int ProfessionId {get; set;}
}
IQueryable<Person_Profession> Person_Profession_Table = ...
First group every person with all ProfessionIds in the Person_Profession_Table.
var personsWithProfessionIds = Persons.GroupJoin(person_profession_table,
person => person.Id,
personProfession => personProfession.PersonId,
person, matchingJoiningItems => new
{
Person = person,
ProfessionIds = matchingJoiningItems
.Select(matchingJoiningItem => matchingJoiningItem.ProfessionId)
.OrderBy(id => id)
.ToList(),
})
In words: take the two tables: Persons and PersonProfessions. From every person take the Id, from every personProfession element take the PersonId, for every person and all matching personProfessions make one new object: this object contains the matching Person, and all ProfessionIds of the matching joiningItems.
From these Persons with their ProfessionIds, keep only those Persons that have all ProfessionIds in your third list
IEnumerable<int> professionIds = professions
.Select(profession => profession.Id)
.OrderBy(id => id);
IEnumerable<Person> matchingPersons = personsWithProfessionIds
.Where(personWithProfessionId => personWithProfessioinId.ProfessionIds
.SequenceEqual(professiondIds))
.Select(personWithProfessionId => perfonWithProfessionId.Person);
Assuming your Lists are related by containing member Lists of the other type,
var AllPersons = new List<Person>();
var AllProfessions = new List<Profession>();
var desiredProfessions = new List<Profession>();
var findPersons = from p in AllPersons
where p.Professions.Any(pp => desiredProfessions.Contains(pp))
select p;

Linq where IN using method syntax

I have been struggling trying to get this one to work and my brain is shot...hoping someone can help out.
I have a table called Company which is the main entity returned from the query. The company table is linked to a table called Category through the table CompanyCategory. The category table has 2 fields that are relevant here: Name and Meaning. These fields contain the same data on a row...ie...Name = "Marketing" and Meaning = "MARKETING". This allows me to query by Meaning, while the display name could potentially change in the future. I will always query the category table by Meaning, and then display the Name.
Since a company can contain 1 to many categories, there are times when I want to return all companies that have a set of categories....say...all companies that are tied to marketing or public relations. Here is the query that I have right now that returns all companies with only the data I want.
IQueryable<ICompanyModel> q = base.Context.Set<KD.CompanyAdventures.Data.Implementation.Company>()
.Include(x => x.Address.City.FirstAdminDivision)
.Include(x => x.CompanyBioInfoes)
.Select(x => new CompanyModel
{
CompanyId = x.CompanyId,
Name = x.Name,
BusinessPhone = x.BusinessPhone,
PrimaryEmail = x.PrimaryEmail,
WebsiteUrl = x.WebsiteUrl,
LogoUrl = x.LogoUrl,
Address = new AddressModel
{
AddressId = x.AddressId,
Address1 = x.Address.Address1,
Address2 = x.Address.Address2,
PostalCode = x.Address.PostalCode,
City = new CityModel
{
CityId = x.Address.City.CityId,
Name = x.Address.City.Name,
FirstAdminDivision = new FirstAdminDivisionModel
{
FirstAdminDivisionId = x.Address.City.FirstAdminDivision.FirstAdminDivisionId,
Name = x.Address.City.FirstAdminDivision.Name
}
}
}
});
I am passing a List<string> to the method (GetCompanies) that has this LINQ query and I need to filter the companies that are returned by that list of category meanings that are being passed in. I have been able to get this to work in a test with 2 simple lists using the following (where list 1 = all employees (my wife and kids names) and list 2 is just the names of the my kids):
IQueryable<string> adultEmployees = employees.Where(emp => !kids.Contains(emp.ToString())).AsQueryable();
But I am not able to get this to work with the company and category example as I can't figure out how to drill down to the meaning with complex objects....ie...not list of strings.
Object classes used by the LINQ query look like the following:
CompanyModel [ CompanyId, CompanyName, List<CategoryModel> ]
CategoryModel [ CategoryId, Name, Meaning ]
Any help is greatly appreciated.
Assume that meanings is a list containing "marketing" and "public relations". If I understand this correctly, you can get companies having CategoryModels's Meaning equals "marketing" or "public relations" like so :
companies.Where(c => c.CategoryModels.Any(cm => meanings.Contains(cm.Meaning)))

Entity Splitting For One-To-Many table relationships

Following this article (What are best practices for multi-language database design?), I have all my database tables splitted in two: the first table contains only language-neutral data (primary key, etc.) and the second table contains one record per language, containing the localized data plus the ISO code of the language. The relationship between the two tables is one to many.
Here a screenshot of the datamodel: https://dl.dropboxusercontent.com/u/17099565/datamodel.jpg
Because the website has 8 languages, for each record in table "CourseCategory" I have 8 record in table "CourseCategoryContents". The same happens with "Course" and "CourseContent"
Then I use Entity Splitting in order to have only one entity for the Course Category and one entity for the Course:
public class CourseCategoryConfiguration : EntityTypeConfiguration<WebCourseCategory>
{
public CourseCategoryConfiguration()
{
Map(m =>
{
m.Properties(i => new { i.Id, i.Order, i.Online });
m.ToTable("CourseCategories");
});
Map(m =>
{
m.Properties(i => new { i.LanguageCode, i.Name, i.Permalink, i.Text, i.MetaTitle, i.MetaDescription, i.MetaKeywords });
m.ToTable("CourseCategoryContents");
});
}
}
public class CourseConfiguration : EntityTypeConfiguration<WebCourse>
{
public CourseConfiguration()
{
Map(m =>
{
m.Properties(i => new { i.Id, i.CategoryId, i.Order, i.Label, i.ThumbnailUrl, i.HeaderImageUrl });
m.ToTable("Courses");
});
Map(m =>
{
m.Properties(i => new { i.LanguageCode, i.Name, i.Permalink, i.Text, i.MetaTitle, i.MetaDescription, i.MetaKeywords, i.Online });
m.ToTable("CourseContents");
});
}
}
Then to retrive the courses in a desired language including their category I do this:
using (WebContext dbContext = new WebContext())
{
// all courses of all categories in the desired language
return dbContext.Courses
.Include(course => course.Category)
.Where(course => course.LanguageCode == lan
&& course.Category.LanguageCode == lan)
.ToList();
}
}
Entity splitting works fine with one-to-one relationships, but here I have one-to-many relationships.
The website has contents (CourseCategories and Courses) in 3 languages ("en", "de", "fr").
EF correctly returns all the Courses with their Category in the right language (eg. in english), but returns each record 3 times. This is because I have the CourseCategory in 3 languages too.
The only one working solution I came up is avoiding using ".Include(Category)", getting all the courses in the desired language in first, then, in a foreach cycle, for each Course retriving its Category in language. I don't like this lazy loading approach, I would like to retrive all the desired data in one shot.
Thanks!
The best solution is to map tables to the model as it then in your model Course class will have a navigation property ICollection<CourseCategoryContent>.
In this case you just project this model to DTO or ViewModel "according to your application design"
e.g.
Your model will look like this
public class Course
{
public int Id {get; set;}
public int Order {get; set;}
public ICollection<CourseCategoryContent> CourseCategoryContents {get; set;}
}
public class CourseCategoryContent
{
public string LanguageId {get; set;}
public string Name {get; set;}
}
Then just create new DTO or ViewModel like :
public class CourseDTO
{
public int Id {get; set;}
public int Order {get; set;}
public string Name {get; set;}
}
Finally do the projection
public IQueryable<CourseDTO> GetCourseDTOQuery ()
{
return dbContext.Courses.Select(x=>new CourseDTO{
Id = x.Id,
Order = x.Order,
Name = x.CourseCategoryContents.FirstOrDefault(lang => lang.LanguageId == lang).Name,
});
}
And note that the return type is IQueryable so you could do any filter, Order or grouping operation on it before hitting the database.
hope this helped
No fix-all answer i'm afraid, every way has a compromise.
I've used both the database approach (10+ language dependent tables) and the resource file approach in fairly large projects, if the data is static and doesn't change (i.e you don't charge a different price or whatever) I would definately consider abstracting language away from your database model and using Resource keys then loading your data from files.
The reason or this is the problem you are experiencing right now where you can't filter includes (this may have changed in EF6 perhaps? I know it's on the list of things to do). You might be able to get away with reading it into memory and filtering them though like you're doing but this meant it wasn't very performant for us and I had to write Stored Procedures that I just passed the iso language and executed in EF.
From a maintenance point of view it was easier as well, for the DB project I had to write an admin console so people could log on and edit values for different languages etc. Using resource files I just copy-pasted the values into excel and emailed them to the people we use to translate.
It depends on the complexity of your project and what you prefer, i'd still consider both approaches in future.
TLDR: options that i've found are:
1) filter in memory
2) lazy load with filter
3) write stored procedure to EF and map that result
4) use resources instead
Hope this helps
EDIT: After looking at diagram it looks like you may need to search against the language dependant values? In that case resources probably won't work. If you're just letting them navigate off a menu then you're good to go.

Resources