public virtual async Task <T> ExecuteQuery <T>(ISqlQuery <T> query)
        {
            var handlerType = typeof(ISqlQueryHandler <,>).MakeGenericType(query.GetType(), typeof(T));
            var handler     = _serviceProvider.GetRequiredService(handlerType);

            // TODO We could make this waaay more efficient
            var result = await(Task <T>) handlerType.GetMethod("Execute").Invoke(
                handler,
                new object[] { Transaction, query });

            return(result);
        }
            public virtual async Task <T> ExecuteQuery <T>(ISqlQuery <T> query)
            {
                var handlerType = typeof(ISqlQueryHandler <,>).MakeGenericType(query.GetType(), typeof(T));
                var handler     = _serviceProvider.GetRequiredService(handlerType);

                await _executeLock.WaitAsync();

                try
                {
                    var wrapperHandlerType = typeof(TaskQueryHandler <,>).MakeGenericType(query.GetType(), typeof(T));
                    var wrappedHandler     = (TaskQueryHandler <T>)Activator.CreateInstance(
                        wrapperHandlerType,
                        handler);

                    return(await wrappedHandler.Execute(Transaction, query));
                }
                finally
                {
                    _executeLock.Release();
                }
            }
            public virtual async IAsyncEnumerable <T> ExecuteQuery <T>(ISqlQuery <IAsyncEnumerable <T> > query)
            {
                var handlerType = typeof(ISqlAsyncEnumerableQueryHandler <,>).MakeGenericType(query.GetType(), typeof(T));
                var handler     = _serviceProvider.GetRequiredService(handlerType);

                await _executeLock.WaitAsync();

                try
                {
                    var wrapperHandlerType = typeof(AsyncEnumerableQueryHandler <,>).MakeGenericType(query.GetType(), typeof(T));
                    var wrappedHandler     = (AsyncEnumerableQueryHandler <T>)Activator.CreateInstance(
                        wrapperHandlerType,
                        handler);

                    var result = wrappedHandler.Execute(Transaction, query);

                    await foreach (var row in result)
                    {
                        yield return(row);
                    }
                }
                finally
                {
                    _executeLock.Release();
                }
            }