Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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
.net 实体框架查询执行两个查询,而不是一个查询_.net_Entity Framework 4_Ef Code First - Fatal编程技术网

.net 实体框架查询执行两个查询,而不是一个查询

.net 实体框架查询执行两个查询,而不是一个查询,.net,entity-framework-4,ef-code-first,.net,Entity Framework 4,Ef Code First,我在实体框架4.3.1中遇到了一个奇怪的行为。在下面的示例中,我创建了一个简单的模型并执行了两个不同的查询,我认为这两个查询应该是等价的。第一个使用All操作符,而另一个使用Where和Any的组合来实现相同的结果 第一个查询如下所示: 执行时,它会导致以下两个数据库查询,其中“额外”查询如下所示: SELECT 1 AS [C1], [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[Project_Id] AS

我在实体框架4.3.1中遇到了一个奇怪的行为。在下面的示例中,我创建了一个简单的模型并执行了两个不同的查询,我认为这两个查询应该是等价的。第一个使用
All
操作符,而另一个使用
Where
Any
的组合来实现相同的结果

第一个查询如下所示: 执行时,它会导致以下两个数据库查询,其中“额外”查询如下所示:

SELECT 
1 AS [C1], 
[Extent1].[Id] AS [Id], 
[Extent1].[Name] AS [Name], 
[Extent1].[Project_Id] AS [Project_Id]
FROM [dbo].[Operations] AS [Extent1]
第二个查询如下所示: 这只执行一个查询,但比较混乱

我不知道为什么第一个版本会引起两个查询。这在我的代码中造成了错误,我无法在一个小示例中重现这些错误

我的问题是:为什么第一个查询执行两个数据库查询?这是我应该报告的错误吗


完整代码如下:

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) { }
    }
}
使用System.Data.Entity;
使用System.Linq;
命名空间EFTest{
班级计划{
静态void Main(字符串[]参数){
var connStr=@“数据源=。\SQLServer;初始目录=EFTest;”
+“集成安全性=True;MultipleActiveResultSets=True”;
使用(var db=newmydbcontext(connStr)){
var result=db.Projects//两个查询!
.其中(p=>p.Id==1)
.All(p=>db.Operations.Any(
o=>o.Name==“foo”&&o.Project.Id==p.Id));
}
使用(var db=newmydbcontext(connStr)){
var result=!db.Projects//单个查询
.其中(p=>p.Id==1)
.Where(p=>!db.Operations.Any(
o=>o.Name==“foo”&&o.Project.Id==p.Id))
.Any();
}
}
}
公共类项目{
公共长Id{get;set;}
公共字符串名称{get;set;}
}
公营课运作{
公共长Id{get;set;}
公共字符串名称{get;set;}
公共虚拟项目{get;set;}
}
公共类MyDbContext:DbContext
{
公共虚拟IDbSet项目{get;set;}
公共虚拟IDbSet操作{get;set;}
公共MyDbContext(字符串名称或连接字符串)
:base(nameOrConnectionString){}
}
}

我认为这不是一个bug。我只是认为这是EF生成特定查询的一种特殊方式

您的项目->运营关系是否已映射?像这样的查询怎么样

var result = !db.Projects
    .Any(p => p.Id == 1 && !p.Operations.Any(o => o.Name == "foo");

如果我添加一个操作集合并执行该查询,我将再次得到一个数据库查询。我对理解EF在另一种情况下执行两个查询的原因很感兴趣,因为我一直假设一个linq查询将始终生成一个db查询。
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) { }
    }
}
var result = !db.Projects
    .Any(p => p.Id == 1 && !p.Operations.Any(o => o.Name == "foo");