使连接实体框架动态化

时间:2020-09-23 17:20:27

标签: c# entity-framework

我有一个连接字符串,我可以毫无问题地完成

<connectionStrings>
    <add name="DbName" 
         connectionString="server=serverName;database=DbTest;user=x;pwd=xxx;"
         providerName="System.Data.SqlClient"  />
</connectionStrings>

我已经连接了实体框架:

public DbContext1() : base("DbName")
{
}

但是我需要对DbContext1进行查询,以从表中获得新的字符串连接以连接到另一个数据库,但是我不知道如何使用从查询中接收到的字符串连接。 / p>

如何使用表中的字符串连接创建新的DbContext

2 个答案:

答案 0 :(得分:0)

执行以下操作:

public DbContext1(string connString) : base(connString)
{
}

您的派生类需要调用的构造函数为this one。字符串参数被视为有效的连接字符串本身或连接字符串的名称。

答案 1 :(得分:0)

这听起来像是多租户方案,在这种方案中,用户通过中央数据库进行身份验证,然后定向到包含自己数据的特定数据库实例。作为身份验证过程中的一个简单示例:

using (var context = new AuthDbContext())
{ // Where AuthDbContext is the central DB containing authentication and the connection string to that user's home database..
     // ... On successful authentication...
     var connectionString = context.Tenants
         .Where(x => x.TenantId == authenticatedUser.TenantId)
         .Select(x => x.ConnectionString)
         .Single();
}

理想情况下,如果要将用户详细信息(用户ID,名称等)保留为会话状态,则可以加载关联的连接字符串,并将其也保留为该数据结构的一部分。

然后创建一个AppDbContextFactory类或UnitOfWork模式类,以注入到您的服务/控制器中,以基于当前用户的连接字符串提供DbContext。

作为一个非常基本的示例:

public interface IUserStateFacade
{
    string CurrentUserConnectionString { get; }
}

public class UserSessionState : IUserStateFacade
{
   public const string UserStateSessionName = "UserState";
   public string CurrentUserConnectionString
   {
       get 
       {
           var userState = (UserSessionState)Session[UserStateSessionName] ?? throw new ApplicationException("Session state missing/expired.");
           return userState.ConnectionString;
       }
   }
}

public interface IAppContextFactory
{
    AppContext Create();
}

public class AppContextFactory
{
    private readonly IUserStateFacade _userState = null;
   
    public AppContextFactory(IUserStateFacade userState)
    {
        _userState = userState ?? throw new ArgumentNullException("userState");
    }
    
    /// <summary>
    /// Create a DbContext. Calling code is responsible for disposing.
    /// </summary>
    public AppContext Create()
    {
        return new AppContext(_userState.ConnectionString);
    }
}

然后在您的控制器等中通常想要使用默认构造函数创建或注入DbContext的对象,将使用类似以下内容的东西:

using (var context = AppContextFactory.Create())
{ }

或注入通过AppContextFactory初始化的值。

对于使用Session的ASP.Net应用程序,您可能需要包装Session,以便依赖项注入库可以解决当前会话状态之外的连接字符串/用户结构。

同样,这只是一个非常简单的示例,它概述了一个方便使用ASP.Net Web应用程序之类的动态连接字符串的选项。应该考虑采取其他安全措施,但希望它可以提供一些有关其结构的想法。