Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使连接实体框架成为动态的_C#_Entity Framework - Fatal编程技术网

C# 使连接实体框架成为动态的

C# 使连接实体框架成为动态的,c#,entity-framework,C#,Entity Framework,我有一个连接字符串,我可以做它没有问题 <connectionStrings> <add name="DbName" connectionString="server=serverName;database=DbTest;user=x;pwd=xxx;" providerName="System.Data.SqlClient" /> </connectionS

我有一个连接字符串,我可以做它没有问题

<connectionStrings>
    <add name="DbName" 
         connectionString="server=serverName;database=DbTest;user=x;pwd=xxx;"
         providerName="System.Data.SqlClient"  />
</connectionStrings>
但是我需要对
DbContext1
进行查询,以便从表中获取新的字符串连接,以连接到其他数据库,但是我不知道如何使用从查询中接收的字符串连接


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

执行以下操作:

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

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

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

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);
    }
}
或者通过AppContextFactory注入初始化的值

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

同样,这只是一个非常基本的示例,概述了一个选项,以促进动态连接字符串(假设类似于ASP.NETWeb应用程序)。应该考虑额外的安全措施,但希望它能提供一些关于如何构建安全措施的想法

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);
    }
}
using (var context = AppContextFactory.Create())
{ }