passing DB Connection object to methods

前端 未结 9 1705
抹茶落季
抹茶落季 2020-12-25 13:29

Was wondering if it is recomended to pass a database connection object around(to other modules) or let the method (in the other module) take care of setting it up. I am lea

相关标签:
9条回答
  • 2020-12-25 14:15

    Personally, I like storing a stack of my current open connection and transactions on top of the Thread Local Storage using SetData and GetData. I define a class that manages my connections to the database and allow it to use the dispose pattern. This saves me the need to pass connections and transactions around, which is something that I think clutters and complicates the code.

    I would strongly recommend against leaving it up to the methods to open connections every time they need data. It will leads to a really bad situation where it is both hard to manage transactions throughout the application and too many connections are opened and closed (I know about connection pooling, it is still more expensive to look up a connection from the pool than it is to reuse an object)

    So I end up having something along these lines (totally untested):

    class DatabaseContext : IDisposable {
    
        List<DatabaseContext> currentContexts;
        SqlConnection connection;
        bool first = false; 
    
        DatabaseContext (List<DatabaseContext> contexts)
        {
            currentContexts = contexts;
            if (contexts.Count == 0)
            {
                connection = new SqlConnection(); // fill in info 
                connection.Open();
                first = true;
            }
            else
            {
                connection = contexts.First().connection;
            }
    
            contexts.Add(this);
        }
    
       static List<DatabaseContext> DatabaseContexts {
            get
            {
                var contexts = CallContext.GetData("contexts") as List<DatabaseContext>;
                if (contexts == null)
                {
                    contexts = new List<DatabaseContext>();
                    CallContext.SetData("contexts", contexts);
                }
                return contexts;
            }
        }
    
        public static DatabaseContext GetOpenConnection() 
        {
            return new DatabaseContext(DatabaseContexts);
        }
    
    
        public SqlCommand CreateCommand(string sql)
        {
            var cmd = new SqlCommand(sql);
            cmd.Connection = connection;
            return cmd;
        }
    
        public void Dispose()
        {
            if (first)
            {
                connection.Close();
            }
            currentContexts.Remove(this);
        }
    }
    
    
    
    void Test()
    {
        // connection is opened here
        using (var ctx = DatabaseContext.GetOpenConnection())
        {
            using (var cmd = ctx.CreateCommand("select 1"))
            {
                cmd.ExecuteNonQuery(); 
            }
    
            Test2(); 
        }
        // closed after dispose
    }
    
    void Test2()
    {
        // reuse existing connection 
        using (var ctx = DatabaseContext.GetOpenConnection())
        {
            using (var cmd = ctx.CreateCommand("select 2"))
            {
                cmd.ExecuteNonQuery();
            }
        }
        // leaves connection open
    }
    
    0 讨论(0)
  • 2020-12-25 14:18

    Here is a little more insight into this problem. I have a class that manages db connections, and have 2 classes that implement an interface. One of the classes is for SQL and the other is of OLAP. The manager is the one that knows which connection to use, so it could pass the exact connection to the type, or the type can create his own connection.

    0 讨论(0)
  • 2020-12-25 14:18

    I would use the web.config

    <configuration>
        <connectionStrings>
            <add name="conn1" providerName="System.Data.SqlClient" connectionString="string here" />
            <add name="conn2" providerName="System.Data.SqlClient" connectionString="string here" />
        </connectionStrings>
    </configuration>
    

    Then you can reference it from anywhere in the application

    0 讨论(0)
提交回复
热议问题