2

我正在使用ExecuteStoreCommand来促进批量删除。

这个作品

// ExecuteStoreCommand syntax via http://stackoverflow.com/a/13024320/740639
// Delete all of today's events
DateTime eventDate = DateTime.Now;

string sql = "DELETE FROM EventCalendar WHERE EventDate = {0}";
context.ObjectContext.ExecuteStoreCommand(sql, new object[] { eventDate });

我想这样做,但它不起作用

我收到 ArgumentException:“不存在从对象类型 System.DateTime[] 到已知托管提供程序本机类型的映射。”

// Delete all of the events for the past 3 days
DateTime[] eventDates = new DateTime[] {
   DateTime.Now.AddDay(-1),
   DateTime.Now.AddDay(-2),
   DateTime.Now.AddDay(-3)
};

string sql = "DELETE FROM EventCalendar WHERE EventDate IN ({0})";
context.ObjectContext.ExecuteStoreCommand(sql, new object[] { eventDates });

建议的解决方案

我可以将我的 DateTime[] 转换为字符串 "'2013-06-24', '2013-06-23', '2013-06-22'" 并将其作为参数传递,但这似乎是一个 hack。

我知道有些库向 EF 添加了批量删除支持,但我现在不想走这条路。

有什么建议么?

4

2 回答 2

1

您可以将日期与 .net 端的分隔符结合起来,将其作为参数传递,然后使用表值函数在服务器端拆分分隔字符串。

传入类似“2013-06-24|2013-06-23|2013-06-22”的内容

http://ole.michelsen.dk/blog/split-string-to-table-using-transact-sql/

于 2013-06-25T16:17:07.893 回答
1

如果您操作字符串,则每次更改日期时,您都会得到稍有不同的 SQL 语句。它可能看起来相同,但字符串不同并且会有不同的哈希值。所以这会破坏执行计划的缓存并降低性能。

您不能真正IN按照您的想法在子句中传递参数。这篇文章中还有一些其他的想法可能会奏效,但如果你阅读了笔记,他们都说他们的表现很糟糕。

如果您可以确定您将有固定数量的输入,您可以使用将它们作为单独参数传递的技术:

... WHERE EventDate IN (@dt1, @dt2, @dt3)

否则,我会采用 Tom 建议的方法,将它们作为分隔字符串传递并在服务器上解析它。

另外 - 由于您正在进行精确匹配,您可能希望使用DateTime.Today而不是捕捉到午夜DateTime.Now,或者使用.Date现有 DateTime 的属性。

这是另一个建议,如果您真的只是想删除过去三天的内容,为什么不这样做呢?

string sql = "DELETE FROM EventCalendar WHERE EventDate BETWEEN {0} AND {1}";
context.ObjectContext.ExecuteStoreCommand(sql,
    new object[] { DateTime.Today.AddDays(-3), DateTime.Today.AddDays(-1) });

或者稍微考虑一下,您可能只使用 sqlgetdate()和类似函数而不是传递参数。

于 2013-06-25T16:35:24.180 回答