Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.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
C# 实体框架中可查询的Linq查询差异_C#_Sql_Linq_Entity Framework - Fatal编程技术网

C# 实体框架中可查询的Linq查询差异

C# 实体框架中可查询的Linq查询差异,c#,sql,linq,entity-framework,C#,Sql,Linq,Entity Framework,在实体框架中,我有一个非常简单的多对多表,将我的批准与我的交易连接起来(如下所示) 我试图在approval对象内部进行查询,以计算approval上的交易量,这应该相对容易 如果我这样做的话,它的工作速度会非常快 int count; EntitiesContainer dbContext = new EntitiesContainer (); var aCnt = from a in dbContext.Approvals where a.id == id

在实体框架中,我有一个非常简单的多对多表,将我的批准与我的交易连接起来(如下所示)

我试图在approval对象内部进行查询,以计算approval上的交易量,这应该相对容易

如果我这样做的话,它的工作速度会非常快

int count;
EntitiesContainer dbContext = new EntitiesContainer ();

var aCnt = from a in dbContext.Approvals
        where a.id == id
        select a.Transactions.Count;

count = aCnt.First();
但是当我这么做的时候

count = Transactions.Count;
还是这个

count = Transactions.AsQueryable<Transaction>().Count();
count=Transactions.AsQueryable().count();
它的速度非常慢。我已经跟踪了服务器上运行的sql,它似乎确实在尝试加载所有事务,而不仅仅是对事务集合执行计数查询

谁能给我解释一下原因吗

其他: 下面是关于这两个类的EF模型的外观

更新:

感谢所有的回复,我认为我错在相信附加到Approval对象的集合将作为IQueryable执行。我必须对dbContext对象执行计数

谢谢大家

var aCnt = from a in dbContext.Approvals
    where a.id == id
    select a.Transactions.Count;
EF自行编译查询,上述查询将编译为
select count
transactions

不像

count = Transactions.AsQueryable<Transaction>().Count(); 
count = Transactions.Count;
count=Transactions.AsQueryable().count();
count=事务。count;

这些将从事务中选择所有记录,然后计算计数。您的第一个方法允许在数据库服务器级别进行计数。它将要求数据库不要返回记录,而是返回找到的记录数量。这是最有效的方法


这并不是说其他方法不能如此有效地工作,但对于其他两行,您首先没有明确表示您正在从批准时的联接检索事务。相反,在另外两行中,您只需要获取Transactions集合本身,并对其进行计数,基本上强制填充集合,以便对其进行计数

访问
a.Transactions
属性时,加载事务列表(延迟加载)。如果您只想获得
计数
,请使用以下方法:

dbContext.Transactions.Where(t => t.Approvals.Any(ap => ap.Id == a.Id)).Count();

其中,
a
获得批准。

您的第一个代码片段导致在数据库服务器上执行查询。这是因为
IQueryable
实例的类型是由实体框架提供的
ObjectQuery
,实体框架执行必要的SQL转换,然后执行

第二个代码片段演示了如何使用
IEnumerable
实例
Count()
在最坏的情况下,通过枚举整个集合来处理它们

在第三个代码段中,您尝试再次将
IEnumerable
设置为
IQueryable
。但是
Enumerable.AsQueryable
方法无法知道它得到的
IEnumerable
来自实体框架。它所能做的最好的事情是将
IEnumerable
封装在
EnumerableQuery
实例中,该实例只需动态编译给定给所有LINQ查询运算符的表达式树,并在内存中执行它们


如果需要由数据库服务器计算计数,则可以手动制定必要的查询(即,在snippet one中编写您已经完成的操作),或者如果不首先使用代码,则可以使用可用的方法。请注意,它实际上是在数据库服务器上执行的,因此,如果您修改了集合但尚未保存更改,则结果将与直接调用
Count
返回的结果不同。

在此上下文中
Transactions
属于哪种类型:
Count=Transactions.Count?@grantwiney完成查询,在我的审批对象上的my ToString()函数中,我吐出了附加的事务数。我可以使用这三个代码段中的任何一个。@RomanKo Transactions是一个ICollection,它是我正在编辑的Approval对象的一部分。实体框架拾取外键关系并默认创建它。
事务
对象的实际类型是什么?也就是说,调用
Transactions.GetType()
并告诉我们类型名称。请参见上文,它只是一个事务对象。EntityFramework创建了一个ICollection对象来针对Approval对象存储它们。我认为当调用IQueryable方法时,它只执行sql查询?IQueryable方法返回可枚举类型,因此它将首先获取所有记录,然后计算计数。这听起来不对,我认为IQueryable方法的威力在于它是在数据库上查询的,而不是作为可枚举对象查询的?@ChristopherTownsend:Using
AsQueryable
仅当底层对象实际实现了
IQueryable
时才启用延迟执行/分析,否则,
AsQueryable
只创建一个将操作转发到基础
IEnumerable
的视图。我看到了,但它不应该看到事务集合已加入到我所在的审批对象中吗?它应该如何看到?我看不到您在代码中使用任何对审批对象的引用。。。在第一个查询中,事务前面没有“a”。