views:

5449

answers:

5

Hi

If I use a join, the Include() method is no longer working, eg:

from e in dc.Entities.Include("Properties")
join i in dc.Items on e.ID equals i.Member.ID
where (i.Collection.ID == collectionID) 
select e

e.Properties is not loaded

Without the join, the Include() works

Lee

A: 

Try the more verbose way to do more or less the same thing obtain the same results, but with more datacalls:

var mydata = from e in dc.Entities
             join i in dc.Items 
                 on e.ID equals i.Member.ID 
             where (i.Collection.ID == collectionID) 
             select e;

foreach (Entity ent in mydata) {
    if(!ent.Properties.IsLoaded) { ent.Properties.Load(); }
}

Do you still get the same (unexpected) result?

EDIT: Changed the first sentence, as it was incorrect. Thanks for the pointer comment!

Tomas Lycken
That is in no way the same thing. Your code will result in n + 1 database queries, where n is the number of rows retrieved. Include results in 1 database query.
Craig Stuntz
I know I'm not doing the same thing - it was a sloppy way of saying that I'd end up with the same results. The main reason to do this was to see if there would be any Properties loaded this way. If not, the problem is not likely in the .Include() syntax, but rather in the data (where associated Property records might be missing, for example...).
Tomas Lycken
Hi TomasIf I load the Properties using Properties.Load() it does load them correctly.If i use Include("Properties") on a query that doesn't include a join, e.g.:from e in dc.Entities.Include("Properties")where (e.ID = id)select e;it works OK.Lee
Lee Atkinson
A: 

Once again I would recommend Linq pad. Helps track if it's really the Include that is the problems. I doubt it.

mhenrixon
A: 

So what is the name of the navigation property on "Entity" which relates to "Item.Member" (i.e., is the other end of the navigation). You should be using this instead of the join. For example, if "entity" add a property called Member with the cardinality of 1 and Member had a property called Items with a cardinality of many, you could do this:

from e in dc.Entities.Include("Properties")
where e.Member.Items.Any(i => i.Collection.ID == collectionID) 
select e

I'm guessing at the properties of your model here, but this should give you the general idea. In most cases, using join in LINQ to Entities is wrong, because it suggests that either your navigational properties are not set up correctly, or you are not using them.

Craig Stuntz
+8  A: 

UPDATE: Actually I recently added another Tip that covers this, and provides an alternate probably better solution. The idea is to delay the use of Include() until the end of the query, see this for more information: Tip 22 - How to make include really include


There is known limitation in the Entity Framework when using Include(). Certain operations are just not supported with Include.

Looks like you may have run into one on those limitations, to work around this you should try something like this:

var results = 
   from e in dc.Entities //Notice no include
   join i in dc.Items on e.ID equals i.Member.ID
   where (i.Collection.ID == collectionID) 
   select new {Entity = e, Properties = e.Properties};

This will bring back the Properties, and if the relationship between entity and Properties is a one to many (but not a many to many) you will find that each resulting anonymous type has the same values in:

anonType.Entity.Properties
anonType.Properties

This is a side-effect of a feature in the Entity Framework called relationship fixup.

See this Tip 1 in my EF Tips series for more information.

Alex

Alex James
great answer, thanks for your help
ChrisHDog
+2  A: 

Try this:

var query = (ObjectQuery<Entities>)(from e in dc.Entities
            join i in dc.Items on e.ID equals i.Member.ID
            where (i.Collection.ID == collectionID) 
            select e)

return query.Include("Properties") 
Bryan2010