How do I handle Database Connections with Dapper in .NET?

前端 未结 9 2061
闹比i
闹比i 2020-12-07 07:52

I\'ve been playing with Dapper, but I\'m not sure of the best way to handle the database connection.

Most examples show the connection object being created in the

9条回答
  •  隐瞒了意图╮
    2020-12-07 08:21

    I wrap connection with the helper class:

    public class ConnectionFactory
    {
        private readonly string _connectionName;
    
        public ConnectionFactory(string connectionName)
        {
            _connectionName = connectionName;
        }
    
        public IDbConnection NewConnection() => new SqlConnection(_connectionName);
    
        #region Connection Scopes
    
        public TResult Scope(Func func)
        {
            using (var connection = NewConnection())
            {
                connection.Open();
                return func(connection);
            }
        }
    
        public async Task ScopeAsync(Func> funcAsync)
        {
            using (var connection = NewConnection())
            {
                connection.Open();
                return await funcAsync(connection);
            }
        }
    
        public void Scope(Action func)
        {
            using (var connection = NewConnection())
            {
                connection.Open();
                func(connection);
            }
        }
    
        public async Task ScopeAsync(Func funcAsync)
        {
            using (var connection = NewConnection())
            {
                connection.Open();
                await funcAsync(connection);
            }
        }
    
        #endregion Connection Scopes
    }
    

    Examples of usage:

    public class PostsService
    {
        protected IConnectionFactory Connection;
    
        // Initialization here ..
    
        public async Task TestPosts_Async()
        {
            // Normal way..
            var posts = Connection.Scope(cnn =>
            {
                var state = PostState.Active;
                return cnn.Query("SELECT * FROM [Posts] WHERE [State] = @state;", new { state });
            });
    
            // Async way..
            posts = await Connection.ScopeAsync(cnn =>
            {
                var state = PostState.Active;
                return cnn.QueryAsync("SELECT * FROM [Posts] WHERE [State] = @state;", new { state });
            });
        }
    }
    

    So I don't have to explicitly open the connection every time. Additionally, you can use it this way for the convenience' sake of the future refactoring:

    var posts = Connection.Scope(cnn =>
    {
        var state = PostState.Active;
        return cnn.Query($"SELECT * FROM [{TableName()}] WHERE [{nameof(Post.State)}] = @{nameof(state)};", new { state });
    });
    

    What is TableName() can be found in this answer.

提交回复
热议问题