Для базы System.Data.Entity.DBContext требуется метод stati c. Обходной путь? - PullRequest
0 голосов
/ 13 января 2020

Я использую клиентскую библиотеку 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 .

Кто-нибудь получил какие-нибудь идеи? скриншот моей проблемы:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...