Entity Framework Include with Func

In Northwind DB, if you want to load categories with products, you will use Include method:

context.Categories.Include("Products")

But what I really find bad is the fact that Products is a string. When we use LINQ, we can't understand it.

So I define an extension method:

public static class ObjectQueryExtension

{

    public static ObjectQuery<T> Include<T>(this ObjectQuery<T> mainQuery, Expression<Func<T, object>> subSelector)

    {

        return mainQuery.Include(((subSelector.Body as MemberExpression).Member as Reflection.PropertyInfo).Name);

    }

}

and I can now doing this:

context.Categories.Include(c => c.Products)

which is I think really better. Isn't it?

 

Published Fri, Jun 6 2008 14:27 by Matthieu MEZIL

Comments

# re: Entity Framework Include with Func

Can I do something like this:

from patient in datacontext.PATIENTS.Include(pat => pat.PATIENTCONTACTS.Where(c => c.ISACTIVE == "T"))

It's throwing a null reference expection? Any idea. Thanks.

Tuesday, June 10, 2008 4:29 AM by Niraj

# re: Entity Framework Include with Func

It's normal. The Include doesn't allow this case.

It should be interesting to change the ExpressionTree to do this but it isn't the goal of my method.

In your case, you can do something like this:

var q = from patient in datacontext.PATIENTS

        select new { Patient = patient, PatientActiveContacts = patient.PATIENTCONTACTS.Where(c => c.ISACTIVE == "T") };

else, if you always want only the active contacts, it should be interesting to specify it directly in your EDM as I showed in my EDM article.

Tuesday, June 10, 2008 4:45 AM by Matthieu MEZIL

# re: Entity Framework Include with Func

I can't use anonymous types. I am working a disconnected mode (EF over WCF To Presentation). I very much need the patients with only active contacts. Any other workarounds? Thanks in advance.

Tuesday, June 10, 2008 5:03 AM by Niraj

# re: Entity Framework Include with Func

The problem is to load on the context only PATIENTCONTACTS you want. 

So, there is probably a better way to do this but you can do this:

var patients = datacontext.PATIENTS;

foreach (var patient in patients)

    context.PATIENTCONTACTS.Where(p => p.PATIENT.PATIENTID == patient.PATIENTID && p.ISACTIVE == "T").ToList();

Tuesday, June 10, 2008 7:35 AM by Matthieu MEZIL

# re: Entity Framework Include with Func

Else, of course, you can create a type with Patient and PatientActiveContacts properties and use the first query without anonymous type.

Tuesday, June 10, 2008 8:28 AM by Matthieu MEZIL

# re: Entity Framework Include with Func

Daniel Simmons propose what is probably the best way for you:

Patient AttachContacts(Patient patient, IEnumerable<PatientContact> contacts)

{

    patient.PATIENTCONTACTS.Attach(contacts);

    return patient;

}

 

var q = from patient in datacontext.PATIENTS

        select new { Patient = patient, PatientActiveContacts = patient.PATIENTCONTACTS.Where(c => c.ISACTIVE == "T") };

var fullQuery = from anonType in q.AsEnumerable()

                select AttachContacts(anonType.Patient, anonType.PatientActiveContacts);

Tuesday, June 10, 2008 2:34 PM by Matthieu MEZIL

# re: Entity Framework Include with Func

I can't see the include() method in my entity class... Why I wonder... my email is nilotpal.das@microsoft.com would you be able to help...?

Thursday, July 17, 2008 6:53 AM by Nilotpal

# re: Entity Framework Include with Func

First, Include is an extension method.

So you need to add the using of the ObjectQueryExtension in your file which will use the Include method.

Moreover, Include is not an extension method for entity class but for ObjectQuery<T>.

Thursday, July 17, 2008 7:02 AM by Matthieu MEZIL

# Entity Framework Include with Func

Tuesday, July 29, 2008 7:14 AM by Jiří {x2} Činčura

# Entity Framework Include with Func

Tuesday, July 29, 2008 7:15 AM by Jiří {x2} Činčura

# re: Entity Framework Include with Func

How would you do a nested includes, something like getting the manufacturer from a product.

Where I would just write .Include("Products").Include("Products.Manufacturer");

context.Categories.Include(c => c.Products).Include(c.Products.Any(p => p.Manufacturer);

How would you do that?

Monday, August 11, 2008 2:01 PM by Robert

# re: Entity Framework Include with Func

Monday, August 11, 2008 2:06 PM by Matthieu MEZIL

# re: Entity Framework Include with Func

Hi Matthieu,

Can you explain how this static class and it's static method are interpreted in to the framework to allow this behavior?

I don't see any use of the partial or override keyword here.

Tuesday, October 07, 2008 2:39 PM by Jared Wein

# re: Entity Framework Include with Func

My Include method is an extension method (keyword this before the first parameter).

Moreover, when you do: c => c.Products (which is a lambda expression), you have an Expression<Func<Category, object> and so I can treat it.

Thursday, October 09, 2008 2:04 AM by Matthieu MEZIL

# re: Entity Framework Include with Func

It does use Reflection though, but that won't cause a performance drop I suppose?

Friday, October 24, 2008 7:18 AM by eXcess

# re: Entity Framework Include with Func

@eXcess : I also think so but I did no test. I just want to remind you that it's a POC.

Martin should try it in a production application this week. I am very interested to know if it is usable in a real world application.

Friday, October 24, 2008 7:29 AM by Matthieu MEZIL

# re: Entity Framework Include with Func

Hi, I'm trying to convert the extension method above into VB. But I get an exception. Here's my VB translation:

<Extension()> Module Module1

   <Extension()> Function Include(Of T)(ByVal mainQuery As ObjectQuery(Of T), ByVal subSelector As Expressions.BLOCKED EXPRESSION

   End Function

End Module

The exception I get is that an UnaryExpression cannot be converted into MemberExpression. Any suggestions?

Thank you!

Friday, November 14, 2008 2:46 AM by Alessandro Del Sole [VB MVP]

# re: Entity Framework Include with Func

Hi Alessandro,

In VB, you must change it like this:

Module ObjectQueryExtension

    <Extension()> _

    Function Include(Of T)(ByVal mainQuery As ObjectQuery(Of T), ByVal subSelector As Expression (Of Func (Of T, Object)))

        Return mainQuery.Include(CType(CType(CType(subSelector.Body, UnaryExpression).Operand, MemberExpression).Member, PropertyInfo).Name)

    End Function

End Module

Friday, November 14, 2008 2:51 PM by Matthieu MEZIL

# What about DataLoadOptions for Entity Framework ObjectContext?

What about DataLoadOptions for Entity Framework ObjectContext? I think the proper way to start this post

Monday, June 15, 2009 12:28 PM by VS2010学习

# re: Entity Framework Include with Func

Hi

What about including several tables?

for example, load shops and categories with products

Wednesday, June 17, 2009 6:17 AM by DonSleza4e

# re: Entity Framework Include with Func

You can do :

context.Products.Include(p => p.Category).Include(p => p.OrderDetails);

If you want more level, you should look at it.

Wednesday, June 17, 2009 6:57 AM by Matthieu MEZIL

# re: Entity Framework Include with Func

Thanks, thats I looking for!

Amazing!

Wednesday, June 17, 2009 7:27 AM by DonSleza4e

# re: Entity Framework Include with Func

This is really much better, but I'm trying to do something like:

this.Context.Countries.Include(c => c.MetroAreas.OrderBy(m => m.Name)).Include(c => c.Regions.OrderBy(r => r.Name));

And its coming up with:

+ Error {System.Windows.Ria.Data.EntityOperationException: Object reference not set to an instance of an object.

  at System.Windows.Ria.Data.HttpDomainClient.GetRequestResult(HttpDomainClientAsyncResult httpAsyncResult)

  at System.Windows.Ria.Data.HttpDomainClient.EndQueryCore(IAsyncResult asyncResult)

  at System.Windows.Ria.Data.DomainClient.EndQuery(IAsyncResult asyncResult)

  at System.Windows.Ria.Data.DomainContext.CompleteLoad(IAsyncResult asyncResult)} System.Exception {System.Windows.Ria.Data.EntityOperationException}

Any ideas?

Monday, October 05, 2009 10:53 AM by Nelson

# re: Entity Framework Include with Func

I think it's very hard to do it. You should look at this.

Thursday, October 08, 2009 6:08 PM by Matthieu MEZIL

# re: Strongly typed eager loading in Entity Framework with Visual Basic

Wednesday, January 27, 2010 2:45 PM by Alessandro Del Sole's Blog

Leave a Comment

(required) 
(required) 
(optional)
(required)