在长循环期间添加新对象

发布于 2024-12-13 05:42:32 字数 517 浏览 2 评论 0原文

我们目前有一个作为 Windows 服务运行的生产应用程序。很多时候,这个应用程序最终会陷入一个循环,可能需要几个小时才能完成。我们使用 .net 4.0 的实体框架进行数据访问。

我正在寻找确认,如果我们将新数据加载到系统中,则在初始化此循环后,不会导致项目被添加到循环本身。当循环初始化时,我们正在寻找“截至”那一刻的数据。虽然我相对确定这将完全像使用 ADO 并在数据上执行循环一样工作(循环仅循环初始化时存在的数据),但我正在寻求同事的确认。

预先感谢您的帮助。

//更新:这里有一些 C# 示例代码 - 问题是相同的,如果将新项目添加到 EF 正在查询的表中,枚举是否会更改?

IEnumerable<myobject> myobjects = (from o in db.theobjects where o.id==myID select o);
foreach (myobject obj in myobjects)
{
    //perform action on obj here
}

We currently have a production application that runs as a windows service. Many times this application will end up in a loop that can take several hours to complete. We are using Entity Framework for .net 4.0 for our data access.

I'm looking for confirmation that if we load new data into the system, after this loop is initialized, it will not result in items being added to the loop itself. When the loop is initialized we are looking for data "as of" that moment. Although I'm relatively certain that this will work exactly like using ADO and doing a loop on the data (the loop only cycles through data that was present at the time of initialization), I am looking for confirmation for co-workers.

Thanks in advance for your help.

//update : here's some sample code in c# - question is the same, will the enumeration change if new items are added to the table that EF is querying?

IEnumerable<myobject> myobjects = (from o in db.theobjects where o.id==myID select o);
foreach (myobject obj in myobjects)
{
    //perform action on obj here
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一腔孤↑勇 2024-12-20 05:42:32

这取决于您的具体实施。

一旦对数据库执行了查询,查询的结果就不会改变(假设您没有使用延迟加载)。为了确保这一点,您可以在检索查询结果后处理上下文——这有效地“切断了检索到的数据和数据库之间的联系”。

延迟加载可能会导致“初始”数据和“新”数据混合;然而,一旦数据被检索,它将成为固定快照并且不易更新。

你提到这是一个长期运行的过程;这意味着可能涉及大量数据。如果您无法完全检索要处理的所有数据(由于内存限制或其他瓶颈),那么您可能无法确保您正在处理原始数据。在执行查询之前,结果不会固定,并且查询执行之前的任何更新都将显示在结果中。

It depends on your precise implementation.

Once a query has been executed against the database then the results of the query will not change (assuming you aren't using lazy loading). To ensure this you can dispose of the context after retrieving query results--this effectively "cuts the cord" between the retrieved data and that database.

Lazy loading can result in a mix of "initial" and "new" data; however once the data has been retrieved it will become a fixed snapshot and not susceptible to updates.

You mention this is a long running process; which implies that there may be a very large amount of data involved. If you aren't able to fully retrieve all data to be processed (due to memory limitations, or other bottlenecks) then you likely can't ensure that you are working against the original data. The results are not fixed until a query is executed, and any updates prior to query execution will appear in results.

雅心素梦 2024-12-20 05:42:32

我认为你最好的选择是改变应用程序的逻辑,这样当“循环”逻辑确定它是否应该进行另一次交互或退出时,你就有机会将新添加的项目加载到列表中。请参阅下面的伪代码:

var repo = new Repository();
while (repo.HasMoreItemsToProcess())
{
   var entity = repo.GetNextItem();
}

让我知道这是否有意义。

I think your best bet is to change the logic of your application such that when the "loop" logic is determining whether it should do another interation or exit you take the opportunity to load the newly added items to the list. see pseudo code below:

var repo = new Repository();
while (repo.HasMoreItemsToProcess())
{
   var entity = repo.GetNextItem();
}

Let me know if this makes sense.

寄居者 2024-12-20 05:42:32

确保发生这种情况的最简单方法 - 如果数据本身不太大 - 是将您从数据库检索的数据转换为 List<>,例如,类似这样的内容(从我当前的项目中随机提取) :

var sessionIds = room.Sessions.Select(s => s.SessionId).ToList();

然后遍历列表,而不是通过IEnumerable<>;否则将被退回。将其转换为列表会触发枚举,然后将所有结果扔到内存中。

如果内存中的数据太多,并且您需要坚持使用 IEnumerable<>,那么问题的答案取决于各种数据库和连接设置。

The easiest way to assure that this happens - if the data itself isn't too big - is to convert the data you retrieve from the database to a List<>, e.g., something like this (pulled at random from my current project):

var sessionIds = room.Sessions.Select(s => s.SessionId).ToList();

And then iterate through the list, not through the IEnumerable<> that would otherwise be returned. Converting it to a list triggers the enumeration, and then throws all the results into memory.

If there's too much data to fit into memory, and you need to stick with an IEnumerable<>, then the answer to your question depends on various database and connection settings.

久夏青 2024-12-20 05:42:32

我会拍摄要处理的 ID 的快照 - 快速并作为事务 - 然后以您今天所做的方式处理该列表。

除了实现不中途更改示例的目标之外,这还使您能够扩展解决方案以跟踪每个项目处理时的状态。对于长时间运行的进程,这对于进度报告、重启/重试功能等非常有帮助。

I'd take a snapshot of ID's to be processed -- quickly and as a transaction -- then work that list in the fashion you're doing today.

In addition to accomplishing the goal of not changing the sample mid-stream, this also gives you the ability to extend your solution to track status on each item as it's processed. For a long-running process, this can be very helpful for progress reporting restart / retry capabilities, etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文