简体   繁体   中英

Entity Framework DbSet<TEntity>.Where(e => true) performance

I am using Entity Framework 6 to access a database.

Is there a performance difference between the following two methods?

public IEnumerable<TEntity> GetAll()
{
    using (var context = new DbContext())
        return context.Set<TEntity>().ToList();
}

and

public IEnumerable<TEntity> GetAll()
{
    using (var context = new DbContext())
        return context.Set<TEntity>().Where(e => true).ToList();
}

I am asking because I would like to use conditional predicates. Something like this the following.

public IEnumerable<TEntity> GetAll(TKey fKey)
{
    using (var context = new DbContext())
        return context.Set<TEntity>()
                      .Where(e => fKey != null ? e.fKey == fKey : true).ToList();
}

where fKey would be a foreign key.

Update : Since many comments focus on my last example, that I agree is a bad use case, I will explain why I am asking.

So I have repository method that looks something like the following.

public class EntityRepository
{
    public IEnumerable<Entity> GetAll(Expression<Func<Entity, bool>> predicate)
    {
        using (var context = new DbContext())
            return context.Set<Entity>.Where(predicate).ToList();
    }
}

And I am using this method form a Web API controller's action-method. Something like the following.

public IHttpActionResult GetEntities(string param1, string param2, string param3)
{
    Expression<Func<Entity, bool>> predicate = e =>
         (param1 != null ? e.field1 == param1 : true)
         && (param2 != null ? e.field2 == param2 : true)
         && (param3 != null ? e.field3 == param3 : true);
    var entities = EntityRepository.GetAll(predicate);
    return Ok(entities);
}

So here I get some query parameters from the URI and I create the predicate based on them. Some of these parameters can be null in which case I don't want to filter on those. But I don't want to create a different predicate for all the combinations of the parameters being null s or not.

I know I could read the entire set and filter one-by-one afterwards, but that would use a lot of memory with big data sets.

So just to clarify my question : Is this a right approach? If all 3 parameters are null (in which case the entire set will be returned) does this method cause any performance setbacks?

I don't know about performance, but you can get around the question all together by building the query before you execute. I think this improves code readability and reduces confusion as well.

public IEnumerable<TEntity> GetAll(TKey fKey)
{
    using (var context = new DbContext())
    {
        IQueryable<TEntity> query = context.Set<TEntity>();

        if (fKey != null)
        {
            query = query.Where(e => e.fKey == fKey);
        }

        return query.ToList();
    }
}

EDIT: Calling your question edit, I think the following method would have the same usage, but avoids unnecessary statements in the sql queries:

public IEnumerable<Entity> GetAll(
    Func<IQueryable<Entity>, IQueryable<Entity>> query)
{
    using (var context = new DbContext())
        return query(context.Set<Entity>).ToList();
}

// then use like this:
EntityRepository.GetAll((entities) =>
    {
        var query = entities;
        if (param1 != null) query = query.Where(e => e.field1 == param1);
        if (param2 != null) query = query.Where(e => e.field2 == param2);
        if (param3 != null) query = query.Where(e => e.field3 == param3);
        return query;
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM