简体   繁体   English

实体框架DbSet <TEntity> 。所以(e =&gt; true)表现

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

I am using Entity Framework 6 to access a database. 我正在使用Entity Framework 6来访问数据库。

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. 其中fKey是外键。

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. 我正在使用此方法形成Web API控制器的动作方法。 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. 所以我在这里从URI中获取一些查询参数,然后根据它们创建谓词。 Some of these parameters can be null in which case I don't want to filter on those. 其中一些参数可以为null在这种情况下我不想对这些参数进行过滤。 But I don't want to create a different predicate for all the combinations of the parameters being null s or not. 但我不想为参数的所有组合创建不同的谓词,无论是否为null

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? 如果所有3个参数都为null (在这种情况下将返回整个集合),此方法是否会导致任何性能挫折?

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: 编辑:调用您的问题编辑,我认为以下方法将具有相同的用法,但避免在SQL查询中不必要的语句:

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;
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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