2

Is it possible to have Include work based on function parameter as used in code below. By going throug MSDN documentation for Include, looks like it's not possible.

public static Response<Person> GetById(int id, bool includeAddress = false
    , bool includeFiles = false
    , bool includeTags = false)
{
    var output = new Response<Person>();

    using (var dbContext = new SmartDataContext())
    {
        dbContext.Configuration.ProxyCreationEnabled = false;
        output.Entity = dbContext.EntityMasters.OfType<Person>()
            .Include(p => includeFiles == true ? p.FileMasters : null)
            .Include(p => includeAddress == true ? p.Addresses : null)
            .Include(p => includeTags == true ? p.Tags : null)
            .FirstOrDefault(e => e.EntityId == id);
    }

    return output;
}

Is there any trick to handle it directly or I have to build expression instead. I am not sure even how would I build an expression for this rather checking in dbContext. I am thinking if I can build expression before entering dbContext scope.

What I am looking for is to have all the conditions resolved before jumping into USING statement. In example below I creating an expression and using it inside USING

public static Response<IEnumerable<ConfigurationType>> GetByAttributeType(int attributeType)
{
    Response<IEnumerable<ConfigurationType>> output = new Response<IEnumerable<ConfigurationType>>();

    System.Linq.Expressions.Expression<System.Func<ConfigurationType, bool>> expressions=null;
    switch (attributeType)
    {
        case 1:
            expressions = a => a.IsItemAttribute == true;
            break;
        case 2:
            expressions = a => a.IsReadPointAttribute == true;
            break;
        default:
            expressions = a => a.IsPersonAttribute == true;
            break;
    }


    using (var context = new SmartDataContext())
    {
        context.Configuration.ProxyCreationEnabled = false;
        output.Entity = context.ConfigurationTypes.Where(expressions).ToList();              
    }

    return output;
}

Similarly what I am expecting is something like this. This sounds weird, just trying to overthink may be if there is a way to resolve p somehow.

IQueryable<Person> query = includeFiles?Include(p=>p.Files):null; //p is undefined
query.Append(includeTags?Include(p=>p.Tags):null);

I am not sure if it's possible or not. If not, please help me understand the reason.

6
  • But in your sample code you're inside the scope of the DbContext. The condition you've placed on it doesn't even make sense, the DbContext is what knows about your entities. What you're asking is impossible. Commented May 23, 2015 at 13:11
  • Isn't it possible with an help of expression tree as well? Commented May 23, 2015 at 13:13
  • @ShantanuGupta I think you need to further elaborate on what you're trying to accomplish. The typical pattern for entity framework is that you create a context instance and then construct your query starting from a context member (e.g. EntityMasters in your case). The pieces of your query can be defined elsewhere, or built using expression trees, but you still start with your context because it is the query provider. Commented May 23, 2015 at 13:32
  • Also you should change the title of your question if it has less to do with conditionally applying Include and more to do with building queries outside of the scope of an entity context. Commented May 23, 2015 at 13:33
  • No. You can't manipulate an object before you create it. The query is built off of the collections that the DbContext exposes. Before you enter the using, there is no object to operate on. Commented May 23, 2015 at 13:39

2 Answers 2

1

Build your query up piece by piece, calling Include conditionally. If you want to perform this work using logic outside of the using statement (and / or outside of the method), you could pass a type that encapsulates the logic for applying the necessary Include statements.

For example:

public static Response<Person> GetById(int id, IIncludeConfiguration<Person> includeConfiguration = null)
{
    var output = new Response<Person>();

    using (var dbContext = new SmartDataContext())
    {
        dbContext.Configuration.ProxyCreationEnabled = false;
        var query = dbContext.EntityMasters.OfType<Person>();

        if(includeConfiguration != null)
        {
            query = includeConfiguration.ApplyIncludes(query);
        }

        output.Entity = query.FirstOrDefault(e => e.EntityId == id);
    }

    return output;
}

public interface IIncludeConfiguration<TEntity> where TEntity : class;
{
    IQueryable<TEntity> ApplyIncludes(IQueryable<TEntity> query)
}

public class PersonIncludeConfiguration : IIncludeConfiguration<Person>
{
    public bool IncludeFiles {get;set;}
    public bool IncludeAddresses {get;set;}
    ....


    public IQueryable<Person> ApplyIncludes(IQueryable<Person> query)
    {
        if(IncludeFiles) query = query.Include(x => x.FileMasters);
        if(IncludeAddresses) query = query.Include(x => x.Addresses);
        ....
        return query;
    }

GetById(1234, new PersonIncludeConfiguration{IncludeFiles = true});
Sign up to request clarification or add additional context in comments.

3 Comments

This can only be done within USING context. I am wondering if its possible before using context.
@ShantanuGupta Please see my edits for an example of how to move this configuration outside of the context.
This is not exactly what I was looking. But it's a good suggestion. Updating my question
0

You can't do it that way but you can always build up the IQuerable on your own. Something like:

var queryable = dbContext.EntityMasters.OfType<Person>();
if (includeFiles)
{
    queryable = queryable.Include(p => p.FileMasters);
}

1 Comment

This can only be done within USING context. I am wondering if its possible before using context.

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.