我想在SQLCE4数据库中使用Entity Framework Code第一种方法。一切似乎都很好,但我有调试SQL查询的问题。我发现来自http://efwrappers.codeplex.com/的EFTracing应该是我需要的,但我不知道如何在没有app.config文件的情况下使用它。我不是这种配置的忠实粉丝。我想只使用C#代码来设置和运行所有内容。我认为使用这样的代码应该没问题:
using (System.Data.Common.DbConnection c =
new EFTracingProvider.EFTracingConnection(
new System.Data.SqlServerCe.SqlCeConnection(conn)))
{
using (var context = new MyContext(c))
{
var a = from data in context.Projects select data;
}
}
但它不起作用。抛出异常:
无法确定连接类型的提供程序名称 EFTracingProvider.EFTracingConnection”。
有没有简单的方法如何只在代码中正确创建包装连接?
答案 0 :(得分:6)
我的问题的解决方案是关注DbContext对象。
public class MyContext : DbContext
{
public MyContext()
: base(CreateConnection("Data Source=file.sdf",
"System.Data.SqlServerCe.4.0"), true)
{ }
public DbSet<Project> Projects { get; set; }
public static bool TraceEnabled = true;
private static DbConnection CreateConnection(string connectionString,
string providerInvariantName)
{
DbConnection connection = null;
if (TraceEnabled)
{
EFTracingProviderConfiguration.RegisterProvider();
EFTracingProviderConfiguration.LogToConsole = true;
string wrapperConnectionString = String.Format(@"wrappedProvider={0};{1}",
providerInvariantName, connectionString);
connection = new EFTracingConnection()
{
ConnectionString = wrapperConnectionString
};
}
else
{
DbProviderFactory factory = DbProviderFactories.GetFactory(providerInvariantName);
connection = factory.CreateConnection();
connection.ConnectionString = connectionString;
}
return connection;
}
}
所以现在我可以只使用上下文,并根据TraceEnabled属性自动为包装或解包的SqlCe创建连接。
using (var context = new MyContext())
{
var a = context.Projects.FirstOrDefault();
}
答案 1 :(得分:0)
跟踪SQL查询的真正方法是调用ToString方法:
var t = from c in _entities.CompanyDetail
select c;
string test = t.ToString();
我不知道EFTracing,但您可能想尝试MVCMiniProfiler。尽管名称MVCMiniProfiler还提供SQL查询分析和工作没有配置文件。
答案 2 :(得分:0)
我通过围绕ObjectContext创建一个包装类并使用该包装而不是原始上下文来完成此操作。这是一个示例上下文包装器:
public partial class LoggedContext : MyContext
{
public LoggedContext()
: this("name=MyEntities") // Adjust this to match your entities
{
}
public LoggedContext(string connectionString)
: base(EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(connectionString)
{
}
private EFTracingConnection TracingConnection
{
get { return this.UnwrapConnection<EFTracingConnection>(); }
}
public event EventHandler<CommandExecutionEventArgs> CommandExecuting
{
add { this.TracingConnection.CommandExecuting += value; }
remove { this.TracingConnection.CommandExecuting -= value; }
}
public event EventHandler<CommandExecutionEventArgs> CommandFinished
{
add { this.TracingConnection.CommandFinished += value; }
remove { this.TracingConnection.CommandFinished -= value; }
}
public event EventHandler<CommandExecutionEventArgs> CommandFailed
{
add { this.TracingConnection.CommandFailed += value; }
remove { this.TracingConnection.CommandFailed -= value; }
}
}
我还有一个静态类,它定义了跟踪输出方法,并有一个静态方法来初始化跟踪。这里:
public static class EFTracingExtensions
{
private static ILogger _logger;
public static void InitSqlTracing(ILogger logger)
{
_logger = logger;
EFTracingProviderConfiguration.RegisterProvider();
if (logger.IsLoggingEnabled()) // Don't add logging hooks if logging isn't enabled
{
EFTracingProviderConfiguration.LogAction = new Action<CommandExecutionEventArgs>(AppendSqlLog);
}
}
private static void AppendSqlLog(CommandExecutionEventArgs e)
{
if (e.Status != CommandExecutionStatus.Executing) // we only care about Finished and Failed
{
StringBuilder msg = new StringBuilder(e.ToTraceString().TrimEnd());
msg.Append(Environment.NewLine);
if (e.Result is SqlDataReader)
{
int rows = ((SqlDataReader)e.Result).HasRows ? ((SqlDataReader)e.Result).RecordsAffected : 0;
msg.AppendFormat("*** {0} rows affected", rows);
}
else if (e.Result is int)
{
msg.AppendFormat("*** result: {0}", e.Result);
}
else
{
msg.AppendFormat("*** finished, result: {0}", e.Result);
}
msg.Append(Environment.NewLine);
msg.AppendFormat(" [{0}] [{1}] in {2} seconds", e.Method, e.Status, e.Duration);
_logger.Log(msg.ToString(), LoggerCategories.SQL);
}
}
}
ILogger是我正在使用的日志记录界面。您需要替换自己的界面/方法。
在我的程序启动时调用InitSqlTracing方法,然后使用LoggedContext类记录Entity Framework生成的所有SQL。
将所有内容与示例代码放在一起:
EFTracingExtensions.InitSqlTracing(logger); // only call this once
using (var context = new LoggedContext())
{
var a = from data in context.Projects select data;
}