C# 查看LINQ生成的SQL-强制转换异常

C# 查看LINQ生成的SQL-强制转换异常,c#,sql,linq,entity-framework,C#,Sql,Linq,Entity Framework,我想分析LINQ在与实体框架对话时生成的SQL,但我遇到了一个异常。我发现ToTraceString()代码处于打开状态,但它抛出: 无法强制转换类型为的对象 '其中枚举致畸器'1[Models.deviceGenetry]' 键入“System.Data.Objects.ObjectQuery” 环境足迹定义: public virtual ICollection<DeviceLogEntry> Errors { get; set; } 实际上,您的结果将是DbQuery类型,而

我想分析LINQ在与实体框架对话时生成的SQL,但我遇到了一个异常。我发现
ToTraceString()
代码处于打开状态,但它抛出:

无法强制转换类型为的对象 '其中枚举致畸器'1[Models.deviceGenetry]' 键入“System.Data.Objects.ObjectQuery”

环境足迹定义:

public virtual ICollection<DeviceLogEntry> Errors { get; set; }

实际上,您的
结果
将是
DbQuery
类型,而不是
ObjectQuery
DbQuery
InternalQuery
上的适配器,它使用
ObjectQuery
,但两者都是内部的,不能从公共API获得)。但如果您想跟踪生成的查询,它非常简单-只需调用查询:

 var trace = result.ToString();
DbQuery
重写了
ToString()
方法,该方法在内部调用
objectQuery.ToTraceString()
并返回基础查询的字符串表示形式

更新:因此,
dbDevice
Device
实体的一个实例,
Errors
只是一个导航属性,那么实体框架的工作方式如下-如果启用了延迟加载,那么在第一次访问
Errors
属性时,它将所有realted
DeviceGenetry
实体加载到
dbDevice
实体。这在内部通过EF为延迟加载生成的代理类实现。您无法获取在这种情况下执行的SQL。对
错误
集合的所有查询都将发生在内存中(即,它将是对对象的Linq,而不是对实体的Linq)。因此,您的
结果将是已加载日志的简单内存迭代器

为了查看生成的查询,您应该在
DbContext
类上为DeviceGenetries创建
DbSet
。然后您应该定义查询:

var query =  from e in db.DeviceLogEntries
             where e.Current == true && 
                   e.LogEntryType == Models.DeviceLogEntryType.Error &&
                   e.DeviceId = dbDevice.Id // or use join
             select e;
现在
query.ToString()
将显示实体框架生成的SQL查询


注意:如果您使用的是Entity Framework 6,那么您也可以使用来记录执行的数据库查询。

result
是查询的结果(Model.DeviceGenetries的可枚举项),而不是objectquery,因此无法进行转换。至少,错误消息似乎是这么说的:)您有visual studio ultimate吗?@oerkelens实际上结果是一个查询,因为它不是executed@SergeyBerezovskiy:在这种情况下,为什么错误消息会说这是一个查询结果?我假设是因为查询get在被引用时执行?我可能找错了树,但如果它;“这是一个查询,我希望错误消息会提到它无法将查询转换为对象查询或类似的内容。@oerkelens error不会说它是查询结果。”。它说您有迭代器,但它并没有说您已经开始枚举从数据库返回的一些数据,或者即使执行了查询,我正要说您很了不起,但我尝试了一下,发现了这个错误
System.Linq.Enumerable+WhereEnumerableIterator
1[Models.deviceogentry]`-我遗漏了什么吗?@Chris你试过执行你的查询吗?如果EF能够生成SQL,那么它应该通过调用
ToString()
返回。还有,完全异常是什么样子的?嘿,我已经用我现在使用的代码更新了我的问题。如果我在
ToString()
之前
ToList()
,我只会得到类型是List@Chris请不要用新代码更新问题,因为它会改变很多问题。你能提供你所有的例外情况吗
System.Linq.Enumerable+WhereEnumerableIterator1[Models.DeviceGeneratory]
也不例外。它看起来像已执行查询的字符串表示
dbDevice
是您的
DbContext
类吗?我使用
ToString
也不例外,正如您所建议的,结果字符串是您引用的,而不是SQL
var query =  from e in db.DeviceLogEntries
             where e.Current == true && 
                   e.LogEntryType == Models.DeviceLogEntryType.Error &&
                   e.DeviceId = dbDevice.Id // or use join
             select e;