[英]Entity Framework query performs two queries instead of one
我在實體框架4.3.1中遇到了奇怪的行為。 在下面的示例中,我正在創建一個簡單的模型並執行兩個我認為應該等效的不同查詢。 第一個使用All
運算符,而另一個使用Where
和Any
的組合來獲得相同的結果。
var result = db.Projects
.Where(p => p.Id == 1)
.All(p => db.Operations.Any(o => o.Name == "foo" && o.Project.Id == p.Id));
執行時,它將導致以下兩個數據庫查詢,其中“額外”查詢如下所示:
SELECT
1 AS [C1],
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent1].[Project_Id] AS [Project_Id]
FROM [dbo].[Operations] AS [Extent1]
var result = !db.Projects // Single query
.Where(p => p.Id == 1)
.Where(p => !db.Operations.Any(
o => o.Name == "foo" && o.Project.Id == p.Id))
.Any();
這將執行一個查詢,但更麻煩。
我不知道為什么第一個版本會引起兩個查詢。 這已經導致我的代碼中出現錯誤,在一個小示例中我無法重現該錯誤。
我的問題是:為什么第一個查詢執行兩個數據庫查詢? 這是我應該報告的錯誤嗎?
完整代碼如下:
using System.Data.Entity;
using System.Linq;
namespace EFTest {
class Program {
static void Main(string[] args) {
var connStr = @"Data Source=.\SQLServer; Initial catalog = EFTest;"
+ " Integrated Security=True; MultipleActiveResultSets=True";
using (var db = new MyDbContext(connStr)) {
var result = db.Projects // Two queries!
.Where(p => p.Id == 1)
.All(p => db.Operations.Any(
o => o.Name == "foo" && o.Project.Id == p.Id));
}
using (var db = new MyDbContext(connStr)) {
var result = !db.Projects // Single query
.Where(p => p.Id == 1)
.Where(p => !db.Operations.Any(
o => o.Name == "foo" && o.Project.Id == p.Id))
.Any();
}
}
}
public class Project {
public long Id { get; set; }
public string Name { get; set; }
}
public class Operation {
public long Id { get; set; }
public string Name { get; set; }
public virtual Project Project { get; set; }
}
public class MyDbContext : DbContext
{
public virtual IDbSet<Project> Projects { get; set; }
public virtual IDbSet<Operation> Operations { get; set; }
public MyDbContext(string nameOrConnectionString)
: base(nameOrConnectionString) { }
}
}
我不認為這是一個錯誤。 我只是認為這是EF生成特定查詢的方式的特質。
您的項目->操作關系是否已映射? 這樣的查詢呢?
var result = !db.Projects
.Any(p => p.Id == 1 && !p.Operations.Any(o => o.Name == "foo");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.