我很想知道EF SaveChanges()
生成了什么sql。所以我搜索谷歌并发现了一个简单的技巧。
public class MyLogger
{
public static void Log(string component, string message)
{
Console.WriteLine("Component: {0} Message: {1} ", component, message);
}
}
也以这种方式挂钩日志功能
using (var db = new TestDBContext())
{
db.Database.Log = s => MyLogger.Log("EFApp", s);
var existingCustomer = db.Customer
.Include(a => a.Addresses.Select(x => x.Contacts))
.FirstOrDefault(p => p.CustomerID == 5);
existingCustomer.FirstName = "Test Customer123";
db.SaveChanges();
}
并看到如下生成的部分插入sql语句
INSERT [dbo].[Addresses]([Address1], [Address2], [IsDefault], [SerialNo], [CustomerID])
VALUES (@0, @1, @2, @3, @4)
SELECT [AddressID]
FROM [dbo].[Addresses]
WHERE @@ROWCOUNT > 0 AND [AddressID] = scope_identity()
为什么我说部分因为没有价值。所以请告诉我怎样才能看到SaveChanges()
函数生成的插入或更新语句的正确值。
答案 0 :(得分:0)
幸运的是,几年前我不得不做类似的事情。您要做的是创建一个从DatabaseLogFormatter派生的新类,重写NonQueryExecuted方法并使用DbCommand参数。此对象将在CommandText属性中保存SQL命令generate,并在Parameters中保存其值的参数。当然,您必须执行命令文本和参数,并创建一个新的sql命令字符串,它看起来像一个ordinaly sql语句。
class EFCustomLogFormatter:: DatabaseLogFormatter
{
public EFCustomLogFormatter(DbContext context, Action<string> writeAction): base(context, writeAction)
{
}
public override void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
//process your command and text
Write(processedCommand);
}
}
完成上述所有操作后,您需要将新记录器连接到DbContext。您必须向DbContex命名空间添加一个新类
public class NewLoggerForEF: DbConfiguration
{
public NewLoggerForEF()
{
SetDatabaseLogFormatter((context, writeAction) => new EFCustomLogFormatter(context, writeAction));
}
}
何时使用
db.Database.Log = command => MyLogger.Log("EFApp", command)
命令字符串格式正确。
希望这有帮助。
实施不是那么好,所以你应该很容易做到。但由于我是Stackoverflow的新手,我将举例说明已实现的方法。 ReplaceWholeWord函数取自Way to have String.Replace only hit "whole words"
public override void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
foreach (DbParameter parameter in command.Parameters)
{
command.CommandText = StringExtendsionsMethods.ReplaceWholeWord(command.CommandText, parametru.ParameterName, "'" + parametru.Value.ToString() + "'");
}
string filterR = command.CommandText.Replace('\r', ' ');
string filterN = faraR.Replace('\n', ' ');
string cleanSQLCommand = filterN.Replace('`', ' ');
Write(string.Format(cleanSQLCommand));
}
同样,它可能需要一些调整,以便彻底测试它。