基于每个LoggedIn用户的数据库连接字符串

时间:2018-03-08 19:22:08

标签: c# asp.net

我有一个包含数百个静态方法和变量的类库,如下所示......

public class General
{
        public static string Con { get; set; }

        public static string Func1()
        {
            using (SqlConnection con = new SqlConnection(Con))
            {
                // My stuff here
            }
        }
        public static string Func2()
        {
            using (SqlConnection con = new SqlConnection(Con))
            {
                // My stuff here
            }
        }

        public static string Funcn()
        {
            using (SqlConnection con = new SqlConnection(Con))
            {
                // My stuff here
            }
        }
}

我将这个类库引用到我的ASP.Net Webform应用程序并从Global.asax的Application_Start事件中分配连接字符串

protected void Application_Start(object sender, EventArgs e)
{
        General.Con = ConfigurationManager.ConnectionStrings["Con"].ConnectionString;
}

一切正常。

现在我想在每个LoggedIn用户的基础上更改数据库连接字符串。

我尝试过:

我将所有用户的连接字符串信息存储在公共数据库中的一个表中,并将它们映射到相应的用户ID。

点击登录按钮,我可以将连接字符串保存到会话。

Session["Con"] = ds.Tables[0].Rows[0][0].ToString();

在类库中我使用了

Public static string Con = System.Web.HttpContext.Current.Session["Con"].ToString();

我收到错误:对象引用未设置为对象的实例。 如果我删除静态,我的所有变量和方法都会给出错误:非静态需要对象引用 如果我在这里使用new关键字,则错误为“无法使用实例引用访问;使用类型名称来限定它“。

然后我用了

public static string Con()
{
        string Con = "";
        HttpContext httpContext = HttpContext.Current;
        if (httpContext.ApplicationInstance.Session.Count > 0)
        {
            if (httpContext.ApplicationInstance.Session["Con"] != null)
                Consd = httpContext.ApplicationInstance.Session["Con"].ToString();
        }
        return Con;
 }

它给了我错误:无法从方法组转换为字符串

请帮帮我......

1 个答案:

答案 0 :(得分:0)

您的类是静态的,这意味着只有一个实例,但您希望以用户为基础更改连接。

这显然无法奏效。我个人建议您允许类的多个实例(非静态)并使用连接字符串作为参数初始化每个实例:

public class General
{
    private string _connectionString;
    public General(string connectionString)
    {
        _connectionString = connectionString;
    }    
}

如果需要,您可以在每个会话中对其进行一次实例化,或者只在每次需要使用它时进行实例化。我不建议在类中添加依赖项(例如连接字符串的来源)。

var data = new General(ds.Tables[0].Rows[0][0].ToString());
var result = data.Func1();

如果由于某种原因,你需要保持类静态,你需要为函数提供连接字符串以便它可以使用它,或者嵌入逻辑以将会话中的连接字符串拉出到方法中:

public static string Func1(string connectionString)
{
    using (SqlConnection con = new SqlConnection(connectionString))
    {
            // My stuff here
    }
}

OR

public static string Func1()
{
    using (SqlConnection con = new SqlConnection(ds.Tables[0].Rows[0][0].ToString()))
    {
        // My stuff here
    }
}

如果你决定走这条路,我建议把连接字符串作为参数传递。

如果您希望保持您的类静态,最后一个选项是使用提供连接字符串的Configurator对象,以抽象该位置:

public interface IConfigurator
{
    string GetConnectionString();
}

public class SessionConfigurator : IConfigurator
{
    public string GetConnectionString()
    {
        var connectionString = Session["Con"].ToString();
        return connectionString;
    }
}

public static class General
{
    public IConfigurator Configurator { get; set; }


    public static string Func1()
    {
        using (SqlConnection con = new SqlConnection(Configurator.GetConnectionString()))
        {
            // My stuff here
        }
    }
}

然后在应用程序启动时:

General.Configurator = new SessionConfigurator();