IDbConnectionInterceptor
の実装者のように、接続を開くたびにいくつかのコードを実行できるようです。これにより、ストアドプロシージャを実行してCONTEXT_INFO
またはSESSION_CONTEXT
変数を設定することができます。私のインターセプタは、次のようになります。これは、データ層のクラスライブラリであるため
public class MAContextInterceptor : IDbConnectionInterceptor
{
private static ITenantIDProvider _tenantIDProvider;
public MAContextInterceptor(ITenantIDProvider tenantIDProvider)
{
_tenantIDProvider = tenantIDProvider;
}
public void Opened(DbConnection connection, DbConnectionInterceptionContext interceptionContext)
{
// Set SESSION_CONTEXT to current tenant ID whenever EF opens a connection
try
{
Guid tenantID = _tenantIDProvider == null ? Guid.Empty : _tenantIDProvider.GetTenantID();
if (tenantID != Guid.Empty)
{
DbCommand cmd = connection.CreateCommand();
cmd.CommandText = "ma_setcontextinfo";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
DbParameter param = cmd.CreateParameter();
param.ParameterName = "@tenantID";
param.Value = tenantID;
cmd.Parameters.Add(param);
cmd.ExecuteNonQuery();
}
}
catch (System.NullReferenceException)
{
//log error
}
}
}
、私は上記の層は、テナントIDを提供実装を提供することを可能にするITenantIDProvider
を追加しました。最終的には、アプリケーションが起動するときにGlobal.asaxに設定されます。また、迎撃器を登録するためにSystem.Data.Entity.Infrastructure.Interception.DbInterception.Add(new MAContextInterceptor(tenantIDProvider));
を呼び出します。
私はbeing problematicを見ることができるすべてのDbContextに適用されるようですが、私の目的のためにはこれが機能します。 This pageかなり徹底的に綴っています。私はこの質問をする前に、なぜ私の検索でそれが出てこないのか分かりません!
['SESSION_CONTEXT'](https://docs.microsoft.com/en-us/sql/t-sql/functions/session-context-transact-sql)は、複数の値を保持するため、優れています(衝突を避ける(CONTEXT_INFOの生のバイトよりも安全な変換を可能にする)バリエーションを格納し、最初の呼び出しの後に値を読み取り専用として設定できるようにします(セキュリティを強化します)。問題は同じままです(接続が開いた後に 'sp_set_session_context'を実行します)。 –
クール、それを指摘してくれてありがとう! – xr280xr
@ JeroenMostertなぜcontext_infoは他のアプリケーションと衝突するのですか?私たちがcontext_infoを設定するたびに、MARSでも問題はなかったと思います。session_contextのドキュメントでは、「SESSION_CONTEXTのMARSの動作はCONTEXT_INFOの動作と似ています。 –