views:

111

answers:

4

Hi,

I have a 2 tables:

Activities       ActivityKeywords
**********       ****************
ID         -->   ActivityID
Name             Keyword

I need to return all activities that match a specific keyword.

+1  A: 

checkout the answer by Craig Stuntz for a cleaner way if you have a relation defined

My previous response was wrong but this works for me.

var activities = from a in db.Activities 
                 join ak in db.ActivityKeywords on a.ID equals ak.ActivityID 
                 where ak.Keyword == "yourkeyword" 
                 select a;
olle
This won't compile, you are trying to use a in both tables.
James
Yeah that looks more along the lines of what I had in mind! I will give it a try
James
It is nearly always wrong to use join in LINQ to Entities. The relationship properties should be used instead.
Craig Stuntz
thanks for the heads up. I had something like (not exactly) you suggest using the relation before but it didn't compile (was missing the any) and when updating the answer I ended up doing the manual join.
olle
A: 

I think you need something like

Give me all Activities which ID are in a list of ActivitiyKeywords.ID's

If that is your question, the you can try this:

var ids = from k in db.ActivityKeywords select k.ActivityID;

var result = from a in db.Activities where ids.Contains(a.ID) select a;

More information here.

eKek0
So the only option is to do 2 queries? I thought I could use a join or something?
James
Don't think about this as 2 querys. Remember that the compiler will optimize this, and therefore it will produce only 1 query with an IN sql clause
eKek0
Contains is not supported in LINQ to Entities (in .NET 3.5 SP1, anyway; I think it's supported in .NET 4). http://msdn.microsoft.com/en-us/library/bb738638.aspx Generally, use Any() instead.
Craig Stuntz
A: 
var results = (from a in Activities
               from k in ActivityKeywords
               where k.Keyword == "keyword" && k.ActivityID == a.ID
               select a).Distinct();
Botz3000
I tested this and it works fine! However, is this more effient than using a join?
James
I don't know. You can check the generated SQL by using ((ObjectQuery<T>)results).ToTraceString()
Botz3000
I don't know about efficient, but it's certainly overcomplex and harder to read than necessary.
Craig Stuntz
You're right. I guess i was thinking too much SQL instead of LINQ.
Botz3000
+5  A: 
var q = from a in Context.Activities
        where a.Keywords.Any(k => k.Keyword == someKeyword)
        select a;

As I said in comments, it's nearly always wrong to use join in LINQ to Entities. The relationship properties should be used instead.

Craig Stuntz
Why is that? Do you have a source for this information?
Richard Hein
Because the relationship properties are designed for this sole purpose. Writing out a join is duplicating the code you already expressed in (1) the DB metadata and (2) your entity model. Do you really want to reinvent this (with probable errors from time to time) every time you write a query?
Craig Stuntz
Craig, thanks for the info, I have only starting learning the EF so not quite sure what is the best method's etc.
James
I think this is the best solution so far. It really reads much more descriptive than the others.
Botz3000