コンテキストごとにすべてのログメッセージをバッファリングしてから、dbコンテキストを破棄してそのバッファを書き出す必要があります。
あなたはその後、あなたはそれが強いを保存せずに動作するはずごとのコンテキスト
class LogGroup
{
static bool ReferenceActiveGroups = true; //I'm not sure if this is needed. It might work fine without.
static HashSet<LogGroup> LogGroups = ReferenceActiveGroups ? new HashSet<LogGroup>() : null;
/// <summary>
/// For the currently being ran query, this outputs the Raw SQL and the length of time it was executed in the Output window (CTRL + ALT + O) when in Debug mode.
/// </summary>
/// <param name="db">The DbContext to be outputted in the Output Window.</param>
public static void Log(ApiController context, AppContext db)
{
var o = new LogGroup(context, db);
o.Initialise();
if (ReferenceActiveGroups) o.Add();
}
public LogGroup(ApiController context, AppContext db)
{
this.context = context;
this.db = db;
}
public void Initialise()
{
db.OnDisposed += (sender, e) => { this.Complete(); };
db.Database.Log = this.Handler;
sb.AppendLine("LOG GROUP START");
}
public void Add()
{
lock (LogGroups)
{
LogGroups.Add(this);
}
}
public void Handler(string message)
{
sb.AppendLine(message);
}
public AppContext db = null;
public ApiController context = null;
public StringBuilder sb = new StringBuilder();
public void Remove()
{
lock (LogGroups)
{
LogGroups.Remove(this);
}
}
public void Complete()
{
if (ReferenceActiveGroups) Remove();
sb.AppendLine("LOG GROUP END");
System.Diagnostics.Debug.WriteLine(sb.ToString());
}
}
をバッファリングを管理するには、このクラスを必要とする、あなたのデシベルコンテキストの処分イベント
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (OnDisposed != null) OnDisposed(this, null);
}
public event EventHandler OnDisposed;
にフックできるようにする必要がありますLogGroupオブジェクトへの参照。しかし、私はまだそれをテストしていません。また、この種のコードをコンテキストに直接含めることができるので、LogGroup参照オブジェクトを保存する必要はありません。しかし、それは移植可能ではありません。 - 要求URI Iはコントローラの参照を渡すので、ログは、いくつかの追加のコンテキスト情報を含むことができること
var db = new MyDbContext();
LogGroup.Log(this, db);
注:コントローラアクション目的球にそれを使用する
。
は、ログの作品は、あなたがログ出力でコメントしたパラメータを見つけること
今、あなたのログ解釈することで動作するように痛みます。通常、それらを手動で適切なSQLパラメータに変更する必要がありますが、パラメータを使用してより大きなSQLクエリのサブセクションを実行することは困難です。
私はEFにログを出力させる1つまたは2つの方法があることは知っています。これらのメソッドは、パラメータの出力方法をよりよく制御できますが、Database.Logを作成するという答えが得られれば、このツールをWinFormsに含めるので、機能的なクエリでクリップボードを書き直すことができます。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
class parameter
{
public string Name;
public string Value;
public string Type;
public string FormattedValue
{
get
{
if (Type == "Boolean")
{
if (Value == "True")
return "1";
else
return "0";
}
else if (Type == "Int32")
{
return Value;
}
else
throw new Exception("Unsupported type - " + Type);
}
}
public override string ToString()
{
return string.Format("{0} - {1} - {2} - {3}", Name, Value, Type, FormattedValue);
}
}
private void button1_Click(object sender, EventArgs e)
{
var sb = new StringBuilder();
var data = Clipboard.GetText(TextDataFormat.UnicodeText);
var lines = data.Split(new string[] { "\r\n" }, StringSplitOptions.None);
var parameters = GetParmeters(lines);
parameters.Reverse();
foreach (var item in lines)
{
if (item.Trim().Length == 0)
continue;
if (item.TrimStart().StartsWith("--"))
continue;
var SQLLine = item;
foreach (var p in parameters)
{
SQLLine = SQLLine.Replace("@" + p.Name, p.FormattedValue);
}
sb.AppendLine(SQLLine);
}
Clipboard.SetText(sb.ToString());
}
private static List<parameter> GetParmeters(string[] lines)
{
var parameters = new List<parameter>();
foreach (var item in lines)
{
var trimed = item.Trim();
if (trimed.StartsWith("-- p__linq__") == false)
continue;
var colonInd = trimed.IndexOf(':');
if (colonInd == -1)
continue;
var paramName = trimed.Substring(3, colonInd - 3);
var valueStart = colonInd + 3;
var valueEnd = trimed.IndexOf('\'', valueStart);
if (valueEnd == -1)
continue;
var value = trimed.Substring(valueStart, valueEnd - valueStart);
var typeStart = trimed.IndexOf("(Type = ");
if (typeStart == -1)
continue;
typeStart += 8;
var typeEnd = trimed.IndexOf(',', typeStart);
if (typeEnd == -1)
typeEnd = trimed.IndexOf(')', typeStart);
if (typeEnd == -1)
continue;
var type = trimed.Substring(typeStart, typeEnd - typeStart);
var param = new parameter();
param.Name = paramName;
param.Value = value;
param.Type = type;
parameters.Add(param);
}
return parameters;
}
}
使用しているコードを表示することは可能でしょうか?小さな**作業**のサンプルは素晴らしいでしょう。 – Enigmativity
@Enigmativityこれは一般的なシナリオです。より多くの文脈のためにこの質問を見てください:https://stackoverflow.com/q/16880687/887092 – Todd