I've inherited this project from the previous guy, and I'm presently in the process of switching over a number of assembled-from-string SQL queries into LINQ to SQL, which I'm told is what makes life in .NET worth living. However, I'm running into problems filtering a Many-to-Many relationship.
The system is a Project Management intranet affair. The primary object/table of note is Project. Project has many Markets, which uses an intermediary table linkProjectMarkets to link them. There's plenty of other stuff going on, but I can take care of that if I can understand this problem, it's all similar.
In short, I can't for the life of me take a list of Market IDs provided by a set of checkboxes, and filter the list of projects down to those which have a relation to the markets whose ids are provided.
The gist of the schema is:
Project: int id, ...(a bunch of metadata)
linkProjectMarkets: int projectId, int marketId
Market: int id, string summary
All of this, any many, many more, is defined in a dbml file and accompanying generated code. To facilitate access between project and market, project has the following addon method:
public partial class project
{
public EntitySet<market> markets
{
get
{
return (EntitySet<market>)from lpm in this._linkProjectMarkets
select lpm.market;
}
set
{
var set = (EntitySet<market>)from lpm in this._linkProjectMarkets
select lpm.market;
set.Assign(value);
}
}
}
Here's the most recent bit of code I'm attempting to use to filter the set of all projects:
var projects =
from p in db.projects
select p;
//MarketFilterList is an IEnumerable of market ids created from the checked checkboxes.
if(MarketFilterList.Count() > 0){
foreach (int mid in MarketFilterList){
projects = projects.Where(p => p.markets.Select(m => m.id).Contains(mid));
/*
Causes "Member access 'Int32 id' of 'PMIS2.market' not legal on type
'System.Data.Linq.EntitySet`1[PMIS2.market]."
*/
}
}
There are a number of other filters to apply, which is why I'm doing it in steps instead of one LINQ statement.
I checked out the designer code; market in linkProjectMarkets is public, and id is public in market. It's my first real C#/.NET experience, so maybe I just don't understand the error message. Apologies if I've given too much, not enough, or not the right information. Please help!
P.S. I already tried LINQ to Entities, and I would have to have a really good reason to try it again.
Edit
Here's something else I tried:
projects = projects.Where(
p => MarketFilterList.Intersect(from m in p.markets select m.id).Count() > 0
);
That one told me:
Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator.
Edit again
Here's the solution based on JTew's answer. If anyone has the real reason why project can't access market directly I'd love to hear it.
projects = projects.Where(p => (from lpm in db.linkProjectMarkets
where MarketFilterList.Contains(lpm.marketId)
select lpm.project).Contains(p));