设置 WHERE 条件以在 ExecuteSqlCommand() 中使用 Ids.Contains()



我正在使用实体框架,我想执行批量更新。加载每一行,更新这些行,然后将它们保存回数据库的效率太低了。

所以我更喜欢使用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/

最新更新