7

I want to add Includes dynamically from input params[]. How can I do this?

This is my code

IQueryable<Work> query = this.ObjectContext.Works
    .Include("EmployeeSender.Person")
    .Include("EmployeeReceiver.Person")
    .Include("WorkCode")
    .Include("WorkFlowStep.WorkFlowFormState")
    .Include("WorkFlow")
    .Include("WorkRoot.EmployeeSender.Person")
    .Include("WorkParent");
Carsten
  • 11,287
  • 7
  • 39
  • 62
Masoomian
  • 740
  • 1
  • 10
  • 25

3 Answers3

9

In a loop, for example:

IQueryable<Work> query = null;  

query = this.ObjectContext.Works;
foreach (var param in params)
{
    query = query.Include(param);
}
var result = query.ToList();

As Christian Dietz mentioned, you can then put this in an extension method so that it becomes reusable.

L-Four
  • 13,345
  • 9
  • 65
  • 109
  • in query.Include(param); this Error is raised. "'System.Linq.IQueryable' does not contain a definition for 'Include' and no extension method 'Include' accepting a first argument of type 'System.Linq.IQueryable' could be found (are you missing a using directive or an assembly reference?)" – Masoomian Apr 17 '13 at 08:02
  • Include is an extension method declared in System.Data.Entity.DbExtensions. You're probably missing a using clause for the System.Data.Entity namespace. – L-Four Apr 17 '13 at 08:13
  • thank you L-Tree, but my project is asp.net and Silverlight .probably this caused System.Linq.IQueryable is different. – Masoomian Apr 17 '13 at 08:39
  • Include is defined in System.Data.Objects Namespace Inside System.Data.Entity.dll – Masoomian Apr 17 '13 at 08:46
3

You can combine L-Three's answer with the extension method in the following question.

Using .Include() when joining a view using Entity Framework

public static IQueryable<T> Include<T>(this IQueryable<T> sequence, params string[] includes) {
    var objectQuery = sequence as ObjectQuery<T>;
    if (objectQuery != null){
        foreach(item in includes){
             objectQuery.Include(item);
        }
        return objectQuery;
    }
    return sequence;
}

Then you should be able to use include like:

IQueryable<Work> query = null;  

query = this.ObjectContext.Works.Include("Something", "Whatever");
Community
  • 1
  • 1
Dietz
  • 578
  • 5
  • 14
3

Lazy loading is not yet possible with EF Core. Refer here.

Alternatively you can use eager loading.

Read this article

Below is the extension method i have created to achieve the eager loading.

Extension Method:

public static IQueryable<TEntity> IncludeMultiple<TEntity, TProperty>(
            this IQueryable<TEntity> source,
            List<Expression<Func<TEntity, TProperty>>> navigationPropertyPath) where TEntity : class
        {
            foreach (var navExpression in navigationPropertyPath)
            {
                source= source.Include(navExpression);
            }
            return source.AsQueryable();
        }

Repository Call:

public async Task<TEntity> FindOne(ISpecification<TEntity> spec)
        {
            return await Task.Run(() => Context.Set<TEntity>().AsQueryable().IncludeMultiple(spec.IncludeExpression()).Where(spec.IsSatisfiedBy).FirstOrDefault());
        }

Usage:

List<object> nestedObjects = new List<object> {new Rules()};

            ISpecification<Blog> blogSpec = new BlogSpec(blogId, nestedObjects); 

            var challenge = await this._blogRepository.FindOne(blogSpec);

Dependencies:

public class BlogSpec : SpecificationBase<Blog>
    {
        readonly int _blogId;
        private readonly List<object> _nestedObjects;

        public ChallengeSpec(int blogid, List<object> nestedObjects)
        {
            this._blogId = blogid;
            _nestedObjects = nestedObjects;
        }

        public override Expression<Func<Challenge, bool>> SpecExpression
        {
            get { return blogSpec => blogSpec.Id == this._blogId; }
        }

        public override List<Expression<Func<Blog, object>>> IncludeExpression()
        {
            List<Expression<Func<Blog, object>>> tobeIncluded = new List<Expression<Func<Blog, object>>>();
            if (_nestedObjects != null)
                foreach (var nestedObject in _nestedObjects)
                {
                    if (nestedObject is Rules)
                    {
                        Expression<Func<Blog, object>> expr = blog => blog.Rules;
                        tobeIncluded.Add(expr);
                    }

                }

            return tobeIncluded;
        }

Will be glad if it helps. Please note this is not a production ready code.

Venkatesh
  • 269
  • 1
  • 11