0

基本上我想要完成的是对数据库中的大量数据执行 CRUD 操作(使用 mvc 4,LINQ)我在这里有一个名为消息的表。我需要查询它并检索那些带有 folderid = 10 的消息(数量超过一百万)

<List>Messages msgList = from msg in db.messages
                         where msg.folderid.equals(10)
                         select msg).tolist();

这将在 msgList 集合中返回一百万。我想分块检索记录,一次说大约 5000 条。请帮忙!

4

3 回答 3

2

其他 2 个当前答案(Kuruvilla 和 Ben)都有您可能需要考虑的警告......

1)使用标志意味着您需要更新此数据库以跟踪已处理的消息..这可能可行,也可能不可行..但这不是唯一的方法

2)如果您确定在调用之间没有添加任何项目,则使用跳过和获取是一个好主意。这称为分页,如果发生这种情况,这可能意味着第二页包含您已经处理的项目!

如果其中任何一点值得关注,那么我建议您按 Id 排序您的消息,跟踪处理的最后一个 id 并在 where 子句中使用它,并与 Take 一起使用:

var msgList = (from msg in db.messages
               order by msg.id
               where msg.id > lastProcessedId
               select msg).Take(5000).ToList();

在处理完每条消息后保留 lastProcessedId,这样如果出现任何问题,您可以从中断的地方继续

于 2013-05-28T03:50:39.160 回答
1

您最好在对前 5000 个进行某些操作并更新每条记录的该标志后使用 Flag。现在您可以再拿 5000 个没有上述标志的。

var msgList = (from msg in db.messages
                         where msg.folderid ==10 && msg.flag
                              select msg).Take(5000).ToList();
于 2013-05-28T03:24:04.527 回答
0

考虑使用SkipandTake来做这种分块方式。阅读此处此处的跳过并采取。在您的情况下,您可能希望包装您的查询(在查询语法中)以调用这些方法(仅在流利的语法中可用)。确保Take在调用 之前使用ToList,即记录被调用到内存中的时间。对于前 100 条记录,使用:

var msgList = (from msg in db.messages
               where msg.folderid == 10
               select msg).Take(100).ToList();

然后对于接下来的 100 条记录使用:

var msgList = (from msg in db.messages
               where msg.folderid == 10
               select msg).Skip(100).Take(100).ToList();

等等。

于 2013-05-28T03:27:03.073 回答