我在Entity Framework 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) { }
}
}
答案 0 :(得分:1)
我不认为这是一个错误。我只是认为这是EF生成特定查询的方式的特质。
您的项目 - &gt;操作关系映射?这样的查询怎么样?
var result = !db.Projects
.Any(p => p.Id == 1 && !p.Operations.Any(o => o.Name == "foo");