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");
4
  • 1
    delete this question as posted another Commented Apr 17, 2013 at 7:42
  • excuse me, send become duplicate non-intentional Commented Apr 17, 2013 at 8:23
  • yeah, thats why i pointed you that, I know it was by mistake, otherwise why one would post a double question within few seconds. Commented Apr 17, 2013 at 8:25
  • possible duplicate of LINQ query: Dynamically add Includes at run time Commented Apr 17, 2013 at 9:27

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

in query.Include(param); this Error is raised. "'System.Linq.IQueryable<KhorasanMIS.Web.Entities.Work>' does not contain a definition for 'Include' and no extension method 'Include' accepting a first argument of type 'System.Linq.IQueryable<KhorasanMIS.Web.Entities.Work>' could be found (are you missing a using directive or an assembly reference?)"
Include is an extension method declared in System.Data.Entity.DbExtensions. You're probably missing a using clause for the System.Data.Entity namespace.
thank you L-Tree, but my project is asp.net and Silverlight .probably this caused System.Linq.IQueryable<Entity> is different.
Include is defined in System.Data.Objects Namespace Inside System.Data.Entity.dll
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");

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.