我必须找到一种方法来找出与EF交互时生成的SQL SELECT是什么。我找到了描述它的MSDN在线帮助ObjectQuery.ToTraceString Method(),我确信我已经完全按照这个例子,但它失败了。我收到以下错误:
CS1503参数2:无法从'string'转换为'System.Linq.Expressions.Expression>'
我不知道为什么我会收到此错误。这是生成错误的代码:
using (var db = new MyDbContext())
{
int idNum = 1;
ObjectQuery<Model.Template> oqTemplate = db.Templates.Where("it.ID = @idNum");
oqTemplate.Parameters.Add(new ObjectParameter("idNum", idNum));
Console.WriteLine(oqTemplate.ToTraceString());
MyDbContext是我定义的类。这是它的定义:
public class MyDbContext : Model.CoreFrameworkEntities
{
public override int SaveChanges()
{
var modifiedEntities = ChangeTracker.Entries()
.Where(p => p.State == EntityState.Modified)
.Select(p => p.Entity);
foreach (var modified in modifiedEntities)
{
Console.WriteLine();
//modified.LastModifiedAt = now;
Console.WriteLine(modified.ToString());
Console.WriteLine();
}
return base.SaveChanges();
}
}
最后Model.CoreframeworkEntities
是定义创建.edmx文件的EF模型。它是.edmx中的一个实体。 (据我所知,.edmx文件中定义的任何实体都是DbContext数据类型。现在,如果这是错的,我很想知道。)
我不确定为什么我会收到错误。在我看来好像我已经遵循代码中的MSDN文章。 MSDN文章不再有效或者我犯了一个错误,可能是我理解了entity-relationship / .edmx文件中的实体是什么。我想帮忙。
答案 0 :(得分:2)
那是因为该文章使用了从ObjectContext继承的上下文。您使用从DbContext
继承的上下文。那个旧ObjectContext
的{{1}}确实有ObjectSets
重载,它接受字符串并返回Where
。但是ObjectQuery
(您使用的)上有DbContext
和DbSets
方法,它们不接受字符串,而只接受表达式,因此您的错误。对于Where
,您通常使用拦截器或DbContext
属性,如下所示:
Database.Log
正如Gert Arnold在评论中提到的那样,你也可以在查询中调用ToString():
db.Database.Log = Console.WriteLine; // or any other handler
var templates = db.Templates.Where(c => c.ID == idNum).ToArray(); // sql will be written to console.
但在某些情况下,您无法执行此操作(例如,您使用db.Templates.Where(c => c.ID == idNum).ToString()
或Count()
等结束查询)。但是当你能做到这一点时,你只需要sql来进行某个查询 - 当然First()
方法更好。