Я использую клиентскую библиотеку elasticscale для управления несколькими осколками и т. Д. c с реестром арендаторов, находящихся в независимой базе данных. на высоком уровне:
- общая БД, в которой есть реестр всех арендаторов, с int tenantid и ключом tenant Guid.
- несколько шардов, находящихся в azure elasti БД c бассейн.
Мой tenantdbcontext принимает tenantkey и tenantid, а метод stati c возвращает открытое соединение db, используя метод shardMap.OpenConnectionForKey. Все работает хорошо.
Тем не менее, я пытаюсь выставить свой tenantdbcontext только на необходимость принять guid ключа tenant ... и внутри моего метода OpenDDRConnection в моем tenantcontext я посмотрю tenantid из кэша и, если он не существует, добавьте его в кеш, вызвав другой commondbcontext, который есть в моем проекте.
В шардах используется int CompanyID и мой Guid карты шардов. Это было сделано намеренно, так как мои пользователи всегда будут использовать только Guids для Companyid, а внутренне мы будем использовать Guids для создания уникального идентификатора компании.
Моя проблема заключается в том, что мой метод openddrconnection в моем tenantxontect является stati c, поэтому я не могу вызывать экземпляры моего глобального класса, получать инъекции DI и, в конечном счете, вызывать мои другие dbcontexts (или мои глобальные классы с областями видимости), почти кажется, что базе System.Data.Entity.DBContext требуется метод / значение stati c для работа.
Вот код:
public TenantDBContext(Guid CompanyID)
: base(OpenDDRConnection(CompanyID), true /* contextOwnsConnection */)
{
}
public static SqlConnection OpenDDRConnection(Guid CompanyID)
{
ListShardMap<Guid> shardMap = null;
string constr = "myconstr";
ShardMapManager shardMapManager;
bool shardMapManagerExists = ShardMapManagerFactory.TryGetSqlShardMapManager(
constr ,
ShardMapManagerLoadPolicy.Lazy,
out shardMapManager);
bool shardMapExists = shardMapManager.TryGetListShardMap<Guid>("mymap", out shardMap);
SqlConnectionStringBuilder tenantConstringBuilder = new SqlConnectionStringBuilder();
tenantConstringBuilder.Password = "shardpass";
tenantConstringBuilder.UserID = "shardusername";
// No initialization
Database.SetInitializer<TenantDBContext>(null);
// Ask shard map to broker a validated connection for the given key
SqlConnection conn = null;
try
{
conn = shardMap.OpenConnectionForKey(CompanyID, tenantConstringBuilder.ConnectionString, ConnectionOptions.Validate);
int CompanyIDint = `<Here is where I'll looking my tenantid to set context to db>`
//Set TenantId in SESSION_CONTEXT to shardingKey to enable Row-Level Security filtering
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = @"exec sp_set_session_context @key=N'CompanyID', @value=@CompanyID";
cmd.Parameters.AddWithValue("@CompanyID", CompanyIDint);
cmd.ExecuteNonQuery();
return conn;
}
catch (Exception ex)
{
if (conn != null)
{
conn.Dispose();
}
throw;
}
}
Примечание. dbcontext из System.Data.Entity, а не из Microsoft.EntityFramework ... это для DDR. Если я создаю свой экземпляр метода OpenDDRConnection (не stati c), моему конструктору dbcontext требуется экземпляр ... и я не могу понять, как это сделать в том же классе, не потеряв свой DI .
Кто-нибудь получил какие-нибудь идеи? скриншот моей проблемы: