簡體   English   中英

實體框架查詢執行兩個查詢,而不是一個

[英]Entity Framework query performs two queries instead of one

我在實體框架4.3.1中遇到了奇怪的行為。 在下面的示例中,我正在創建一個簡單的模型並執行兩個我認為應該等效的不同查詢。 第一個使用All運算符,而另一個使用WhereAny的組合來獲得相同的結果。

第一個查詢如下所示:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM