Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架DbSet<;tenty>;。其中(e=>;true)性能_C#_Database_Performance_Entity Framework_Entity Framework 6 - Fatal编程技术网

C# 实体框架DbSet<;tenty>;。其中(e=>;true)性能

C# 实体框架DbSet<;tenty>;。其中(e=>;true)性能,c#,database,performance,entity-framework,entity-framework-6,C#,Database,Performance,Entity Framework,Entity Framework 6,我正在使用EntityFramework6访问数据库 以下两种方法之间是否存在性能差异 public IEnumerable<TEntity> GetAll() { using (var context = new DbContext()) return context.Set<TEntity>().ToList(); } 我正在使用这个方法形成一个WebAPI控制器的动作方法。类似下面的内容 public IEnumerable<TEnt

我正在使用EntityFramework6访问数据库

以下两种方法之间是否存在性能差异

public IEnumerable<TEntity> GetAll()
{
    using (var context = new DbContext())
        return context.Set<TEntity>().ToList();
}
我正在使用这个方法形成一个WebAPI控制器的动作方法。类似下面的内容

public IEnumerable<TEntity> GetAll(TKey fKey)
{
    using (var context = new DbContext())
        return context.Set<TEntity>()
                      .Where(e => fKey != null ? e.fKey == fKey : true).ToList();
}
public class EntityRepository
{
    public IEnumerable<Entity> GetAll(Expression<Func<Entity, bool>> predicate)
    {
        using (var context = new DbContext())
            return context.Set<Entity>.Where(predicate).ToList();
    }
}
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);
}
public IHttpActionResult GetEntities(字符串参数1、字符串参数2、字符串参数3)
{
表达式谓词=e=>
(param1!=null?e.field1==param1:true)
&&(param2!=null?e.field2==param2:true)
&&(param3!=null?e.field3==param3:true);
var entities=EntityRepository.GetAll(谓词);
返回Ok(实体);
}
因此,这里我从URI中获取一些查询参数,并基于它们创建谓词。其中一些参数可以是
null
,在这种情况下,我不想对这些参数进行筛选。但是我不想为参数的所有组合创建一个不同的谓词,无论参数是否为
null
s

我知道我可以读取整个数据集,然后一个接一个地进行过滤,但这会占用大数据集的大量内存


那么,我想澄清一下我的问题:这是一种正确的方法吗?如果所有3个参数都为
null
(在这种情况下,将返回整个参数集),此方法是否会导致性能下降?

我不知道性能,但您可以通过在执行之前构建查询来解决所有问题。我认为这提高了代码的可读性,也减少了混乱

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();
    }
}
public IEnumerable GetAll(TKey-fKey)
{
使用(var context=new DbContext())
{
IQueryable query=context.Set();
如果(fKey!=null)
{
query=query.Where(e=>e.fKey==fKey);
}
返回query.ToList();
}
}
编辑: 调用您的问题编辑,我认为以下方法将具有相同的用法,但避免了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;
    });
public IEnumerable GetAll(
Func查询)
{
使用(var context=new DbContext())
返回查询(context.Set).ToList();
}
//然后像这样使用:
EntityRepository.GetAll((实体)=>
{
var查询=实体;
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);
返回查询;
});

如果您知道
fkey
为空,为什么要使用它呢?只是不要将它添加到表达式中。至于性能,它取决于SQL查询和生成的执行计划。前两个查询可能会创建相同的SQL或等效的执行计划。第三个不会,它将创建一个“一网打尽”的查询,这通常会导致糟糕的执行计划,就像您试图在更高级别的类似ORM的实体框架上实现通用存储库反模式一样。检查
DbSet
。您自己的类提供了哪些DbSet没有的功能?如果您的类只是一个薄薄的包装器,那么为什么要使用它呢?实体没有外键,它们具有关系和导航属性。如果您的“存储库”不理解这一点,如果它不能利用关系,因为它是“通用的”,那么它会造成伤害,而没有真正的好处。它将抽象级别降低到低于EF或任何其他人提供的抽象级别,或是对答案的感谢!我可以看到我的坏例子造成了一些混乱,所以请检查我的更新!没有混乱。Catch-all查询很糟糕。是的,空值会导致性能问题,因为它们会导致缓存和重用错误的执行计划。Jesse表明,在使用LINQ时,您一开始并不需要它们。为什么catch all查询是badIt还可以提高性能<代码>fKey!=无效的e、 fKey==fKey:true将被转换为SQL,生成一个查询,该查询的(缓存的)执行计划将取决于第一次执行时fKey的值。生成错误执行计划的可能性为50%,例如扫描表而不是使用索引的计划。seekI expect这对简单的
var
不起作用,因为
context.Set
。Where()
具有不同的结果类型。可能
IQueryable查询=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;
    });