none
Repository, EF Code First and Include() RRS feed

  • Question

  • Hi

    I am creating a Repository to get entities out of EF context
    I am using EF Code First

    I created the following method

    public List<User> GetAll(params Expression<Func<User, object>>[] includes)
    {
        List<string> includelist = new List<string>();
        foreach (var item in includes)
        {
            MemberExpression body = item.Body as MemberExpression;
            if (body == null)
                throw new ArgumentException("The body must be a member expression");
            includelist.Add(body.Member.Name);
        }
     
        using (DatabaseContext context = new DatabaseContext())
        {
            var userList = context.Users;
           
            includelist.ForEach(x=>userList.Include(x));
            return userList.ToList();
        }
    }



    Note: in this case I use a concrete entity, but in a real case the method will use generics

    To use this metodo in the bussines layer, I write

    List<User> userList = repository.GetAll(x=>x.Companies);

    The problem is that the Include() not work, this optimize the query with the JOIN to load related entities (the asociate entities remain conected with the context), if I use

    List<Company> companiesList = userList[0].Companies;

    I get the error:

    The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.


    I need load user entity and his Companies asociates, both disconected to EF context

    I thought that the Include() load the related collection

    How I return a disconected entity and related asociation?

    regards

                

    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    Friday, September 14, 2012 10:00 PM

Answers

  • Hi Leandro,

    The method Include() returns a new DbQuery<T> which when iterated will function as desired, the problem is that you're calling the Include() method on the DbSet<T> but then simply iterating the DbSet<T> without the includes. You'd need to reassign the userList variable each time you call the Include() method. Notice that you need to declare the type of your userList variable as a DbQuery<T> in order to assign the results of Include() to it (or you could just use IQueryable<T>).

        using (DatabaseContext context = new DatabaseContext())
        {
            DbQuery<User> userList = context.Users;
           
            foreach (var include in includes)
            {
                userList = userList.Include(include);
            }
    
            return userList.ToList();
        }

    Saludos,

    Tyler

    Sunday, September 16, 2012 10:40 PM

All replies

  • Hi Leandro,

    The method Include() returns a new DbQuery<T> which when iterated will function as desired, the problem is that you're calling the Include() method on the DbSet<T> but then simply iterating the DbSet<T> without the includes. You'd need to reassign the userList variable each time you call the Include() method. Notice that you need to declare the type of your userList variable as a DbQuery<T> in order to assign the results of Include() to it (or you could just use IQueryable<T>).

        using (DatabaseContext context = new DatabaseContext())
        {
            DbQuery<User> userList = context.Users;
           
            foreach (var include in includes)
            {
                userList = userList.Include(include);
            }
    
            return userList.ToList();
        }

    Saludos,

    Tyler

    Sunday, September 16, 2012 10:40 PM
  • Hi

    excellent, it works perfect

    I just changed these points

     using (DatabaseContext context = new DatabaseContext())
        {
            DbQuery<User> userList = context.Users;
           
            includelist.ForEach(x=> userList = userList.Include(x));
            return userList.ToList();
        }

    then the repository returns the related entity defined in the include

    many thanks

    regards


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    Tuesday, September 18, 2012 6:10 AM