[英]Delete multiple rows in PostgreSQL with Entity Framework using WHERE IN clause
I have a postgresql database and what I am trying to do is remove a bunch of rows from a table in as few queries as possible.我有一个 postgresql 数据库,我想要做的是在尽可能少的查询中从表中删除一堆行。 So looping is not a good option.
所以循环不是一个好的选择。 I am using NPGSQL for the postgres driver.
我正在为 postgres 驱动程序使用 NPGSQL。
I have the code below but it is not working.我有下面的代码,但它不起作用。
string[] namesToDelete = PromosReplies.
PromosRepliesLoaded.GroupBy(pr => pr.Name).
Select(r=>r.Key).ToArray();
long[] repliesIdsToDelete = context.PromosReplies.
Where(pr => namesToDelete.Contains(pr.Name)).
Select(r => r.Idx).ToArray();
if (repliesIdsToDelete.Length > 0)
{
foreach (var name in namesToDelete)
{
context.Database.ExecuteSqlCommand("DELETE FROM messages WHERE name = {0}", name);
}
string idToDelete = String.Join(",", repliesIdsToDelete);
int result = context.Database.ExecuteSqlCommand(
"DELETE FROM message_translations WHERE idx IN ({0})",
repliesIdsToDelete);
I get a "ERROR: 22P02: invalid input syntax for integer:" error when trying to execute the last query.尝试执行最后一个查询时出现“错误:22P02:整数输入语法无效:”错误。 Is there a way to overcome this?
有没有办法克服这个问题? If yes can something similar be done with first delete statement where I have to use a string?
如果是,可以使用第一个删除语句完成类似的操作,我必须使用字符串?
update I'm not working with EF, but here's the way to use array as parameter with Npgsql:更新我不使用 EF,但这里是使用数组作为 Npgsql 参数的方法:
var cmd = NpgsqlCommand();
cmd.CommandText = "select * from test where id = any(@list)";
cmd.Connection = "**************************";
cmd.Parameters.Add("list", NpgsqlDbType.Array | NpgsqlDbType.Integer);
cmd.Connection.Open();
var r = cmd.ExecuteReader();
So I suppose in EF it would something like:所以我想在 EF 中它会是这样的:
var par = new NpgsqlParameter("list", NpgsqlDbType.Array | NpgsqlDbType.Text);
var par.Value = namesToDelete;
int result1 = context.Database.ExecuteSqlCommand(
"DELETE FROM messages WHERE name = any(@list)",
par
);
old I don't like this one at all because it could lead to SQL injection:老我根本不喜欢这个,因为它可能导致 SQL 注入:
int result1 = context.Database.ExecuteSqlCommand(
String.Format(
"DELETE FROM messages WHERE name in ({0})",
String.Join(",", namesToDelete.Select(x => "'" + x + "'"))
)
);
int result2 = context.Database.ExecuteSqlCommand(
String.Format(
"DELETE FROM message_translations WHERE idx in ({0})",
String.Join(",", repliesIdsToDelete)
)
);
I'm not an expert in EntityFramework, but I think when you use context.Database.ExecuteSqlCommand(command, str)
, str is used as a parameter, so your command becomes DELETE FROM message_translations WHERE idx in ('1, 2, 3, 4')
(note single quotes, '1, 2, 3, 4'
is actually a string on server side).我不是 EntityFramework 的专家,但我认为当您使用
context.Database.ExecuteSqlCommand(command, str)
, str 用作参数,因此您的命令变为DELETE FROM message_translations WHERE idx in ('1, 2, 3, 4')
(注意单引号, '1, 2, 3, 4'
实际上是服务器端的字符串)。
You could use table-valued parameters if your DB was SQL server, may be it's possible to pass array as a parameter into PostgreSQL, have to try later.如果您的数据库是 SQL 服务器,您可以使用表值参数,也许可以将数组作为参数传递给 PostgreSQL,稍后再试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.