如何先用SqlKata编译复杂的查询,然后再执行
How to compile complex queries with SqlKata first and execute later
我想使用 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。最好我应该能够 运行 两者。
我不明白你想做什么。
你可以这样使用它。
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;
}
对于精通C#/.NET的人来说,这可能是基础知识,但我想做的是将params注入到使用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
.
我想使用 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。最好我应该能够 运行 两者。
我不明白你想做什么。 你可以这样使用它。
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;
}
对于精通C#/.NET的人来说,这可能是基础知识,但我想做的是将params注入到使用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
.