none
Wanting Lambda Expression for .Include("..")

    Question

  • I often make mistakes when I type my string literal for how to not lazy load an object in my code first EF model.  That is, I have code like this:

    var rec = db.Users.Include("EmailAccount").FirstOrDefault(a => a.Username == username);

    I really want code like

    var rec = db.Users.Include(o=>o.EmailAccount).FirstOrDefault(a => a.Username == username);

    I saw this post:  http://tomlev2.wordpress.com/2010/10/03/entity-framework-using-include-with-lambda-expressions/ 

    from a while back that makes it seem like you have to wrote your own complex extension methods.  Is this still true?  Is there an easier way to do it?


    Peter Kellner http://peterkellner.net Microsoft MVP • ASPInsider

    Thursday, March 08, 2012 11:45 PM

Answers

All replies

  • This still requires you to write your own extension method, as you can't extend the classes easily.  However, it's not too bad, provided you isolate the construction of a string from an expression tree into its own class/method.

    Once you have the extension method, you can use it anywhere...

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Thursday, March 08, 2012 11:46 PM
  • Hi Reed,

    This article seems to imply it's built in somehow if you use an include (which I did).

    Am I missing something?

    http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/1bdb0b6f-82ca-4f54-9d8f-3daacaece0b7


    Peter Kellner http://peterkellner.net Microsoft MVP • ASPInsider

    Friday, March 09, 2012 12:03 AM
  • You're have  "using System.Data.Entity;", and using EF 4.1 or later?  If so, it should just work...


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Friday, March 09, 2012 12:12 AM
  • Hi, 

    "make mistakes when I type my string literal

    I guess this is the common problem we face when we are in need of specifying property name.

    If we have the utility class like this, 

     public static string PropertyName<TEntity>(Expression<Func<TEntity, object>> expression) where TEntity : class
                {
                    MemberExpression memberExpression = null;
                   
                    if (expression.Body.NodeType == ExpressionType.Convert)
                        memberExpression = ((UnaryExpression)expression.Body).Operand as MemberExpression;
                    else if (expression.Body.NodeType == ExpressionType.MemberAccess)
                        memberExpression = expression.Body as MemberExpression;
                    
                    if (memberExpression == null)
                        throw new Exception("Property Expression is Invalid");
    
                    return memberExpression.Member.Name;
                }

    you can use as 

    var rec = db.Users.Include(PropertyName(u => u.EmailAccount)).FirstOrDefault(a => a.Username == username);


    If this post answers your question, please click "Mark As Answer". If this post is helpful please click "Mark as Helpful".

    Friday, March 09, 2012 1:34 AM
  • Now I'm confused.  It seems like half of the answers say you can do it without adding extra code and half say you don't have to. i perfer the half that say you don't have to, but the one above proposed as an answer says you do have to.

    Peter Kellner http://peterkellner.net Microsoft MVP • ASPInsider

    Friday, March 09, 2012 2:13 PM
  • Reed clarified this by saying you have to use 4.1 to get the built in Lambda support you wanted.   I validated his answer by looking at the class doc. for EF 4.1.  If you are not able to use EF 4.1 or higher then you have to do it the other way.

    JP Cowboy Coders Unite!

    Friday, March 09, 2012 2:40 PM
  • Hi, 

    sorry to keep you in confusion, I did suggested in this way, because you are using earlier version of EF that doesn't support Lambda.


    If this post answers your question, please click "Mark As Answer". If this post is helpful please click "Mark as Helpful".

    Friday, March 09, 2012 3:39 PM
  • Hi everyone and thanks for the efforts.

    What was confusing me is intellisense did not work, however once I typed it in full, it was recognized.

    Below is a simple example of working code

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Text;
    using System.Data.Entity;
    
    namespace ConApp
    {
        internal class Program
        {
            private static void Main()
            {
                Database.SetInitializer<SiteDB>(new SiteDBInitialize());
                using (var myContext = new SiteDB())
                {
                    var x = myContext.Presidents.Include(o => o.BirthPlace);
                }
            }
        }
        a
        public class SiteDB : DbContext
        {a
            public DbSet<Presidents> Presidents { get; set; }
        }
    
        public class BirthPlace
        {
            [Key]
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public long Id { get; set; }
    
            public string City { get; set; }
        }
    
        public class Presidents
        {
            [Key]
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public long Id { get; set; }
            public string LastName { get; set; }
    
            // New Columns for first migration
            public int YearElected { get; set; }
            public bool CurrentPresident { get; set; }
    
            // New Column for second migration
            public string Party { get; set; }
    
            public BirthPlace BirthPlace { get; set; }
        }
    
        public class SiteDBInitialize :
            CreateDatabaseIfNotExists<SiteDB>
        {
            protected override void Seed(SiteDB context)
            {
                context.Presidents.Add(new Presidents
                                           {
                                               LastName = "Reagan",
                                               CurrentPresident = false,
                                               YearElected = 1980
                                           });
                context.Presidents.Add(new Presidents
                                           {
                                               LastName = "Bush",
                                               CurrentPresident = false,
                                               YearElected = 1992
                                           });
                context.Presidents.Add(new Presidents
                                           {
                                               LastName = "Obama",
                                               CurrentPresident = true,
                                               YearElected = 2008
                                           });
                context.SaveChanges();
            }
        }
    
    }
    


    Peter Kellner http://peterkellner.net Microsoft MVP • ASPInsider

    Friday, March 09, 2012 7:50 PM