【问题标题】:How to compile complex queries with SqlKata first and execute later如何先用 SqlKata 编译复杂的查询,然后再执行
【发布时间】:2019-09-24 07:43:28
【问题描述】:

我想使用 SqlKata 创建和编译一个 SQL 查询,然后在其他一些函数中执行这个查询。根据文档,这并不明显,尤其是对于复杂的查询。

我已尝试将查询转换为字符串然后运行它,但这似乎不是正确的做法,而且该字符串对于复杂的查询不能很好地编译。

    public class TradeLoader : ITradeLoader
    {

        public SqlResult CreateTradeQuery(Target targets, Group groups, DateTime fromTime)
        {
            var compiler = new SqlServerCompiler();
            var query = new Query().FromRaw(@"
                    [trades] AS t WITH (NOLOCK)
                    LEFT JOIN [info] AS i WITH (NOLOCK)
                    ON t.Id = i.Id
                ")
                .Select("i.Name", "t.Price", "t.Volume")
                .WhereTime("t.CreatedDate", ">", fromTime);

            var subQuery = new Query(@"
                    [trades] AS t WITH (NOLOCK)
                    LEFT JOIN [info] AS i WITH (NOLOCK)
                    ON t.Id = i.Id
                ");
            foreach (var target in targets)
            {
                subQuery.OrWhere(q => q.WhereIn("i.Name", groups.Keys).WhereIn("i.GroupName", target.Value));
            }

            query.Where(subQuery);
            SqlResult result = compiler.Compile(query);
            return result; // How to execute this somewhere else?
        }
    }

我不清楚如何使用 SqlKata.Execution 或 System.Data.SqlClient 在其他地方执行此查询。最好我应该能够同时运行它。

【问题讨论】:

  • 为什么不返回 Query 对象而不是 SqlResult 并稍后执行?

标签: c# .net-core sqlkata


【解决方案1】:

我不明白你想做什么。 你可以这样使用它。

public SqlResult CreateTradeQuery(Target targets, Group groups, DateTime fromTime)
{
    var query = GetDefaultQuery();
    query.Select("i.Name", "t.Price", "t.Volume");
    query.Where("t.CreatedDate", ">", fromTime);
    query.Where(GetSubQuery(targets,groups),"subQuery");
    SqlResult result = compiler.Compile(query);
    return result;
}

private Query GetSubQuery(Target targets, Group groups)
{
    var subQuery = GetDefaultQuery();
    foreach (var target in targets)
    {
        subQuery.OrWhere(q => q.WhereIn("i.Name", groups.Keys).WhereIn("i.GroupName", target.Value));
    }
    return subQuery;
}

private Query GetDefaultQuery()
{
    var query = new Query("trades as t");
    query.LeftJoin("info as i","i.Id","t.Id");
    return query;
}

【讨论】:

    【解决方案2】:

    对于精通C#/.NET的人来说,这可能是基本知识,但我想做的是将参数注入使用SqlKata创建的SQL查询中,然后在不使用SqlKata的情况下运行它。最后,我是通过以下方式做到的(可能还有其他方法可以做到这一点):

    public class TradeLoader : ITradeLoader
    {
        ...
    
        public async Task<SomeDataType> RunQuery()
        {
            ...
            var sqlCommand = CreateTradeQuery(someTargets, someGroups, someDateTime);
            using (SqlConnection sql = new SqlConnection(_connectionString))
            {
                sql.Open();
                var command = new SqlCommand(sqlCommand.Sql, sql) {CommandTimeout = _timeout};
                foreach (var (name, value) in sqlCommand.NamedBindings)
                {
                    var parameter = command.CreateParameter();
                    parameter.ParameterName = name;
                    parameter.Value = value;
                    command.Parameters.Add(parameter);
                }
    
                using (SqlDataReader dataReader = await command.ExecuteReaderAsync())
                {
                    while (await dataReader.ReadAsync())
                    {
                        // read data here
                    }
                }
            }
            return data;
        }
    }
    

    这允许您使用 SqlKata 构建查询,但使用其他库运行查询,例如我使用 System.Data.SqlClient 的示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-11
      • 1970-01-01
      • 2012-12-24
      • 1970-01-01
      • 1970-01-01
      • 2016-06-07
      • 1970-01-01
      相关资源
      最近更新 更多