1

I'm trying to create a generic GetAll method that works for each of my model classes in my ASP.NET MVC4 project.

Here's my code:

public static List<T> GetAll(params string[] includeProperties)
{
    using (MovieSiteDb db = new MovieSiteDb())
    {
        var entities = db.Set<T>();
        foreach (var includeProperty in includeProperties)
        {
            entities.Include(includeProperty);
        }
        return entities.ToList();
    }
}

Now I call it the following way (Movie inherits the GetAll method):

Movie.GetAll("Category");

However I get an error when I try to access the foreign key "Category" in the view model. Why isn't it being included?

Jordan Axe
  • 3,823
  • 6
  • 20
  • 27

3 Answers3

6

I can't say I've used EF myself, but in general LINQ doesn't mutate queries when you call a method - instead it returns a new query. So if you change your code to:

DbQuery<T> entities = db.Set<T>();
foreach (var includeProperty in includeProperties)
{
    entities = entities.Include(includeProperty);
}

you may find that fixes the problem.

(The type of entities is now fixed to DbQuery<T> rather than using var to implicitly type it to DbSet<T>, as Include returns DbQuery<T>.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • should not we use lambda expression with include method?? – Neel Oct 18 '13 at 10:07
  • may be silly question sorry i am new in this field!! – Neel Oct 18 '13 at 10:09
  • Ahh yes of course - that makes sense. By the way I've heard I could use lambda instead of strings - do you know how this would work? If not I'll just mark this as the answer since it solved my initial problem - thanks. – Jordan Axe Oct 18 '13 at 10:09
  • In addition you'll need to drop the `var` and use `DbQuery entities = ...` – H H Oct 18 '13 at 10:13
  • @HenkHolterman: Thanks, I wasn't sure about that. Will add it. – Jon Skeet Oct 18 '13 at 10:20
2

Here's a chunk of my generic repository with an AllIncluding method that can be called with lambda expressions

private readonly IUnitOfWork _UnitOfWork;

protected MyContext Context { get { return Uow.Context; } }

protected IUnitOfWork Uow
{
    get { return _UnitOfWork; }
}

public RepositoryBase(IUnitOfWork unitOfWork)
{
    _UnitOfWork = unitOfWork;
}

public virtual IQueryable<T> All
{
    get
    {
        return Context.Set<T>();
    }
}

public virtual IQueryable<T> AllIncluding(params Expression<Func<T
                                          , object>>[] includeProperties)
{
    IQueryable<T> query = All;
    foreach (var includeProperty in includeProperties)
    {
        query = query.Include(includeProperty);
    }
    //string sql = query.ToString();
    return query;
}

Here's an example how I call it from my Controller:

   IRepository<Answer> repo = _Uow.AnswerRepository;
   IOrderedQueryable<Answer> answers = repo.AllIncluding(answer => answer.Questions)
                                        .OrderBy(answer => answer.SortOrder)
                                        .ThenBy(answer => answer.Text);

Getting into units of work and other stuff here tho'

Colin
  • 22,328
  • 17
  • 103
  • 197
  • This might be a dumb question but could you give me an example as how to call this? I tried: AllIncluding(m => m.MovieCategory); But that gives me an error. – Jordan Axe Oct 18 '13 at 10:37
  • That should work. What error are you getting. I've included an example of how I use it – Colin Oct 18 '13 at 10:45
  • I'm getting the error: Cannot convert lambda expression to type 'System.Linq.Expressions.Expression>[]' because it is not a delegate type – Jordan Axe Oct 18 '13 at 10:48
  • I think it's something to do with the fact that I have chosen to return IQueryable from my repository. One of the hardest or misunderstood aspects of LINQ http://stackoverflow.com/a/215580/150342 ;-) – Colin Oct 18 '13 at 11:05
  • I see - I guess I'll do some more research – Jordan Axe Oct 18 '13 at 11:17
  • After a few attempts I got your example to work in my project - I don't know what I did wrong but thanks a lot - it works great now! – Jordan Axe Oct 18 '13 at 12:16
0

for ur concern about lambda expression what i know it u can do below

var prodcutmasters = this.db.ProdcutMasters.Include(p => p.CategoriesMaster);
return (prodcutmasters.ToList());
Neel
  • 11,625
  • 3
  • 43
  • 61