views:

1072

answers:

2

Here's a bunch of things I tried... hopefully you can extrapolate from it what I'm trying to do and what I'm doing wrong. Okay so I'm having problems with loading related entities when using this DoQuery:

   public ObjectQuery<E> DoQuery(ISpecification<E> where)
   {
        return (ObjectQuery<E>)_ctx.CreateQuery<E>("[" + typeof(E).Name + "]").Where(where.EvalPredicate);
   }

If I just use this, I end up getting an object back that contains all proper parameters except the ones that are related entities... ie. if one is a UserID that's referenced to the User table, I do not get back the User object as well.

I read up that you can do a .Include("User") to do an Eager Load of the entity... but it doesn't work when I try this:

public ObjectQuery<E> DoQuery(ISpecification<E> where)
{
     return (ObjectQuery<E>)_ctx.CreateQuery<E>("[" + typeof(E).Name + "]").Include("User").Where(where.EvalPredicate);
}

I also checked to make sure the Entity Set Name and model name are "User", which they are. The only other thing I could think of is to put multiple things in the ("[" + typeof(E).Name + "]") but I'm not sure how to include multiple entities in there... Here's what I tried since I saw someone said you could load multiple by putting a . inbetween.

public ObjectQuery<E> DoQuery(ISpecification<E> where)
{
     return (ObjectQuery<E>)_ctx.CreateQuery<E>("[" + typeof(E).Name + "].[User]").Where(where.EvalPredicate);
}

But that didn't work...

If I'm not on the right track please let me know. Does anyone know how to load the related entities when using ObjectContext.CreateQuery? Any suggestions or insight helps.

Thanks,
Matt

A: 

The previous rev of this answer is incorrect as pointed out by Craig in the comments. Since I can't delete this answer (because of comments?) I'll at least try to leave something that's not incorrect.

Assuming you have a model (.edmx) with two entities Product and ProductDetail. Further assuming you want to retrieve a given product and its related details.

I would make sure the following works (given you have a product with an ID of 1 that have detail records):

var result = ctx.CreateQuery<Product>("Products").Include("ProductDetails").Where(p => p.ProductId == 1);

In the Include statement above, "ProductDetails" is a property on Product. If that works, I would try the following:

public ObjectQuery DoQuery<E>(Expression<Func<E, bool>> filter)
{
    string entitySetName = GetEntitySetName(typeof(T)); 
    return (ObjectQuery<E>)_ctx.CreateQuery<E>(entitySetName).Include("ProductDetails").Where(filter);
}

Note that GetEntitySetName() is not a built-in function

var result = DoQuery<Product>(p => p.ProductId == 1);
Kim Major
I'm still not getting the user objects returned... I've put breaks on those lines and checked that the proper entitySetNames are being entered in there.
Matt
If you expand the "Results View" of the query in the debug visualizer, you have a Users property. When you expand that, do you get a Count of Users?
Kim Major
No, it just says null
Matt
This answer is wrong. Include takes a **property** name, not an entity name or entity set name. CreateQuery, OTOH, takes ESQL, which can include the entity set name, but isn't really an entity set name *per se.*
Craig Stuntz
I stand corrected by Craig. Include takes a property name.
Kim Major
+2  A: 

CreateQuery takes an ESQL statement. So you can write something like:

public ObjectQuery<E> DoQuery(ISpecification<E> where)
{
    var esql = String.Concat(
         "SELECT VALUE e1 FROM OFTYPE(", 
         GetEntitySetName(typeof(E)),
         ", ", 
         typeof(T).FullName, 
         ") AS e1");
    return Context.CreateQuery<T>(esql).Include("User").Where(where.EvalPredicate);
}

...where GetEntitySetName is a method you write which returns the string entity set name for your entity type, or use an eager loading strategy.

Why OFTYPE? If you have inheritance in your model, this ESQL would return ObjectQuery<TParent> instead of ObjectQuery<TChild> without it.

Finally, the Include only works if the entity E has a property named User. The type and entity set name are irrelevant to Include.

Craig Stuntz