C# 实体框架DbSet<;tenty>;。其中(e=>;true)性能
我正在使用EntityFramework6访问数据库 以下两种方法之间是否存在性能差异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
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查询=我完全同意这对我的例子来说是一个更好的解决方案,但我的第一个问题仍然有效。我进一步解释了为什么我会在问题更新中使用它。@DánielTarsoly我想Panagiotis Kanavas的评论回答了这个问题。
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;
});