C# 设置在ExecuteSqlCommand()中使用Ids.Contains()的位置条件

C# 设置在ExecuteSqlCommand()中使用Ids.Contains()的位置条件,c#,sql-server,entity-framework,dbcontext,C#,Sql Server,Entity Framework,Dbcontext,我正在使用实体框架,我想执行批量更新。加载每一行,更新这些行,然后将它们保存回数据库,这样效率太低了 所以我更喜欢使用DbContext.Database.ExecuteSqlCommand()。但是,我如何使用此方法用ID列表中包含的ID更新所有这些行 这是我到目前为止所拥有的 IEnumerable<int> Ids; DbContext.Database.ExecuteSqlCommand("UPDATE Messages SET Viewed = 1 WHERE Id IN

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

所以我更喜欢使用
DbContext.Database.ExecuteSqlCommand()
。但是,我如何使用此方法用ID列表中包含的ID更新所有这些行

这是我到目前为止所拥有的

IEnumerable<int> Ids;
DbContext.Database.ExecuteSqlCommand("UPDATE Messages SET Viewed = 1 WHERE Id IN (@list)", Ids);
IEnumerable ID;
DbContext.Database.ExecuteSqlCommand(“已查看的更新消息集=1,其中(@list)”中的Id),Id);
我意识到我可以用正确的查询手动构建一个字符串,但我更愿意像通常建议的那样传递参数


有没有办法做到这一点?

您仍然可以构建参数并将其包含在参数化查询中

在生成查询时,该查询类似于此

updatemessages SET view=1,其中Id位于(@p0、@p1、@p2、…、@pn)
如此给定

IEnumerable<int> Ids;

您可以使用尽可能多的参数生成查询字符串,而不是使用精确的值生成查询字符串。 因此,您将获得smth,如:

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也有类似的链接:

我建议研究表值参数是如何工作的(尽管TVP与存储过程一起使用,而不是与编写的命令一起使用)。这应该有很多问题。例如。除此之外,我认为您必须将列表作为字符串传递,并以某种方式拆分它(例如字符串拆分函数)或使用LIKE语句。关于这一点也有很多问题,因此应该很容易找到满足您要求的内容。@ZLK:谢谢,但我真的不确定这里如何使用表值参数。我链接的问题有一个链接,指向一个简短的示例,说明如何实现这一点:(我不相信用简单的executesqlcommand语句就可以做到这一点,但我可能错了),创建一个将该类型的TVP作为参数的存储过程,然后通过传递包含您的值的数据表来执行该存储过程。如果现在运行代码,会出现什么错误?您没有指定(尽管我可以推测它失败的原因,因为在
DbParameter
中可能没有List或IEnumerable的序列化程序,无法将其转换为
DbType
s中的一个
DbType
)@马克:老实说,我甚至没有运行它。500.00美元表示它不可能像我想的那样解析它。好吧,我只是尝试了一下。它似乎没有引发异常,但似乎也没有做任何事情。我认为这是一个很好的答案,但不是OP想要的答案。有趣的建议。可能是你能用
E做的最好的xecuteSqlCommand
。这就是我目前使用EF的方式。我已经搜索了您很长时间的请求。当我在一些MS文档中看到它时,我决定使用这种格式。@Nkosi:显然,在某一点上,它需要付出更多的努力,但实际上并没有任何效率。但看起来这仍然更有效ent@Nkosi:到目前为止,我收到一个异常
System.ArgumentException:“不存在从对象类型System.Int32[]到已知托管提供程序本机类型的映射。”
。是否尝试了该代码?
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);