我正在使用实体框架,我想执行批量更新。加载每一行,更新这些行,然后将它们保存回数据库的效率太低了。
所以我更喜欢使用DbContext.Database.ExecuteSqlCommand()
.但是如何使用此方法使用ID列表中包含的ID更新所有这些行呢?
这是我到目前为止所拥有的。
IEnumerable<int> Ids;
DbContext.Database.ExecuteSqlCommand("UPDATE Messages SET Viewed = 1 WHERE Id IN (@list)", Ids);
我意识到我可以使用正确的查询手动构建一个字符串,但我更愿意按照通常的建议传递我的参数。
有什么办法可以做到这一点吗?
您仍然可以生成参数并将其包含在参数化查询中。
查询在生成时如下所示
UPDATE Messages SET Viewed = 1 WHERE Id IN (@p0, @p1, @p2, ..., @pn)
所以给定
IEnumerable<int> Ids;
然后
var parameters = Ids.Select((id, index) => new SqlParameter(string.Format("@p{0}", index), id));
var parameterNames = string.Join(", ", parameters.Select(p => p.ParameterName));
var query = string.Format("UPDATE Messages SET Viewed = 1 WHERE Id IN ({0})", parameterNames);
int affected = DbContext.Database.ExecuteSqlCommand(query, parameters.ToArray());
您可以生成具有任意数量参数的查询字符串,而不是生成具有精确值的查询字符串。所以你会得到这样的信息:
DbContext.Database.ExecuteSqlCommand("UPDATE Messages SET Viewed = 1 WHERE Id IN (@p0,@p1,@p2,...,@pN)", Ids);
通过这样的SMTH:
var paramsDef = string.Concat(Ids.Select(x=>$"{(Ids.IndexOf(x) > 0 ? "," : "")}p{Ids.IndexOf(x)}"));
DbContext.Database.ExecuteSqlCommand($"UPDATE Messages SET Viewed = 1 WHERE Id IN {paramsDef}", Ids);
我发现人们使用SqlCommand做类似事情的一些链接:http://www.svenbit.com/2014/08/using-sqlparameter-with-sqls-in-clause-in-csharp/http://nodogmablog.bryanhogan.net/2016/01/parameterize-sql-where-in-clause-c/