【发布时间】:2020-12-02 00:10:04
【问题描述】:
想做一些 SQL 处理,并通过在我的项目中添加 dbml 来尝试 LinqToSql 功能。 它是一个 foreach 循环(大约 3k 个条目),我打算从中执行一个简单的 where 子句并在 2 个表上执行后续 deleteallonsubmit。 (分别记录 23 万和 540 万)。
根据我在 Spark 延迟计算中工作的理解和假设。在我调用 SubmitChanges() 之前,我认为它不会在 foreach 的每次迭代中或者更简单的说法中进行数据库调用并在实际表上执行“某事”。我从 SQL 分析器中注意到,它确实在每次迭代中都进入了 SQL 服务器,并且每次迭代大约需要 1 秒。
下面是代码
internal static void RemoveAllDataStartingFrom()
{
HistoricalRefreshDateCheckerDataContext dbContext = new HistoricalRefreshDateCheckerDataContext();
logger = (ILog)LogManager.GetLogger("HDP.allMins");
var counter = 0;
allMins.ToList().ForEach((v) =>
{
logger.Info("For each started");
var toBeDeletedDaily = dbContext.DailyIntervalDatas.Where(x => x.Date >= v.Value && x.Id == v.Key);
logger.Info("Daily where completed");
dbContext.DailyIntervalDatas.DeleteAllOnSubmit(toBeDeletedDaily);
logger.Info("Daily deleteall completed");
var toBeDeletedFifteenMinute = dbContext.FifteenMinuteDatas.Where(x => x.Date >= v.Value && x.Id == v.Key);
logger.Info("Fifteen Where completed");
dbContext.FifteenMinuteDatas.DeleteAllOnSubmit(toBeDeletedFifteenMinute);
logger.Info("Fifteen deleteall completed ");
logger.Info("ended. counter = " + counter++);
});
dbContext.SubmitChanges();
}
我的意图
我想将整个事情作为一个批处理命令运行(通过进行 1 或 2 次数据库调用)。我本可以编写一个动态内联脚本并在 DB 上触发它。但我想我错误地使用了 LinqToSql 功能。
以下是我的日志文件
编辑
allMins 代码
internal static void FetchIndividualStartDates(DateTime startDate)
{
HistoricalRefreshDateCheckerDataContext refDBData = new HistoricalRefreshDateCheckerDataContext();
var allMaxes = refDBData.DailyIntervalDatas
.GroupBy(x => x.Id)
.Select(
row =>
new
{
row.Key,
MaxDate = row.Max(r => r.Date)
});
allMaxes.ToList().ForEach((a) =>
{
allMins[a.Key] = Convert.ToDateTime(a.MaxDate);
});
}
其他 Profiler 日志
在下面的每个 DeleteAllOnSubmit 被调用
exec sp_executesql N'SELECT [t0].[x], [t0].[y], [t0].[z], [t0].[a], [t0].[b], [t0].[c], [t0].[e], [t0].[Date], [t0].[Id], [t0].[_ID] AS [_ID]
FROM [dbo].[FifteenMinuteData] AS [t0]
WHERE ([t0].[Date] >= @p0) AND ([t0].[Id] = @p1)',N'@p0 datetime,@p1 varchar(8000)',@p0='2020-08-10 00:00:00',@p1='1365'
当 SubmitChanges() 被调用时,他会被触发
出于数据安全目的,我编辑了一些信息
【问题讨论】:
-
什么是
allMins,它来自哪里? -
@GertArnold : allMins 是一个键值对字典。目前有 3k+ 个条目。我通过一些琐碎的查询来准备它。但是,是的,我正在循环它。
-
您可能应该将该查询与您在此处显示的查询集成。
-
@GertArnold :添加代码。
-
与 any 一样,ORM(也是实体框架)对象被拉入内存,修改或标记为删除,然后单独保存回数据库。这正是每次迭代中发生的事情。没有办法改变这种根深蒂固的行为。这就是为什么您不应该将 ORM 用于批量数据库操作的原因。这些第三方库只是治标不治本,都有自己的问题。我的座右铭:做对或不做。 IE。存储过程。这就是我要说的全部内容。
标签: sql linq linq-to-sql