C# 根据条件将查询追加到何处
我有这样一个问题:C# 根据条件将查询追加到何处,c#,entity-framework,C#,Entity Framework,我有这样一个问题: if (catId == null || catId == 0) { productVM = db.Products .Include(x => x.Category) .ToArray() .Select(x => new ProductVM(x)) .ToList(); } else { product
if (catId == null || catId == 0)
{
productVM = db.Products
.Include(x => x.Category)
.ToArray()
.Select(x => new ProductVM(x))
.ToList();
}
else
{
productVM = db.Products
.Include(x => x.Category)
.ToArray()
.Where(x => x.CategoryId == catId)
.Select(x => new ProductVM(x))
.ToList();
}
这是可行的,但正如您所看到的,这两个查询之间的唯一区别是,其中(x=>x.CategoryId==catId)
有没有一种更优雅的方式来编写此命令?只需重新分配查询:
var query = db.Products;
if (condition)
query = query.Where(criteria);
var list = query.ToList();
另一种方式
var products = db.Products.Include(x => x.Category).ToArray()
if (catId == null || catId == 0)
{
productVM = products.Select(x => new ProductVM(x)).ToList();
}
else
{
productVM = products.Where(x => x.CategoryId == catId)
.Select(x => new ProductVM(x)).ToList();
}
实体框架实际上不会查询数据库,直到您将数据具体化,例如使用
ToList()
或迭代结果。因此,您可以在运行时构建查询,而无需访问数据库:
var query = db.Products.Include(x => x.Category);
if(catId != null && catId != 0)
{
//Add a where clause
query = query.Where(x => x.CategoryId == catId);
}
productVM = query
.ToList()
.Select(x => new ProductVM(x));
请注意,我删除了
ToArray
调用,因为这也使数据具体化,这意味着数据上的每个后续方法都作用于数据库中的整个表。您可以扩展Where语句,以包括catId上的null或0测试。如果数据库中的字段catId可为空或值为0,则此操作可能不起作用
productVM = db.Products
.Include(x => x.Category)
.Where(x => catId == null || catId == 0 || x.CategoryId == catId)
.Select(x => new ProductVM(x))
.ToList();
您还应该删除ToArray()因为它从数据库查询整个Products表,然后在客户端的内存中执行过滤和投影。这可能是个坏主意,因为它将
catId
检查传递到数据库。在我们的团队中,当条件转为简单类型时,我们在SQL/Linq查询中广泛使用这个概念,“而且效果很好。@DavidG-将条件传递给数据库服务器更为理想,因为这意味着无论catId的值如何,都将在服务器上创建和使用单个执行计划。实际上,这是完全错误的。”。将其传递给服务器意味着您正在传递服务器实际不需要的参数,并且查询计划仅针对catId为null或不为null的情况进行优化。最好有两个查询计划,每种情况一个。这看起来不错,但我得到一条红线,表示基本上无法将IQueryable转换为List
,并且productVM
声明如下:List productVM代码>我想我需要某种类型的强制转换,但不确定正确的方式?是否缺少结尾的ToList
?错误是:无法隐式将类型“System.Collections.Generic.IEnumerable”转换为“System.Collections.Generic.List”。存在显式转换(是否缺少转换?)红线显示在db.Products.Include(x=>x.Category)下
和query.Where(x=>x.CategoryId==catId)代码>哎呀,我刚才看到了一个复制/粘贴错误!再试一次