2013-06-20 28 views
1

我有两个应用程序:一个应用程序是asp.net,另一个是在后台运行的Windows服务。EF数据库并发

在后台运行的windows服务正在执行一些数据库任务(读取和更新),而用户可以通过asp.net应用程序对数据库执行其他操作。所以,我很担心它,例如,在窗口服务,我收集了一些记录满足条件的,然后我在它们之间迭代,是这样的:

IQueryable<EntityA> collection = context.EntitiesA.where(<condition>) 
foreach (EntityA entity in collection) 
{ 
    // do some stuff 
} 

所以,如果用户修改在以后使用记录循环迭代,EF考虑的记录是什么值?原始检索时执行:

context.EntitiesA.where(<condition>) 

或新的一个由用户修改并位于数据库?

据我所知,迭代过程中,EF被采取在需求每条记录,我的意思是,一个接一个,所以读取下一个记录为下一次迭代时,这个记录对应于从收集:

context.EntitiesA.where(<condition>) 

或位于数据库(用户刚刚修改的那个)?

谢谢!

+1

EF上枚举使用延迟加载。所以,当你调用foreach时,集合将被枚举。这意味着EF会在那个时候调用数据库。这意味着如果枚举已经开始,并且记录通过网站更新,那么在foreach循环中使用的记录将是旧版本或“原始检索”,如你所说。 – RollemIra

+2

@RollemIra你所描述的称为'延期执行'。延迟加载与第一次访问时加载的导航属性有关。 –

+0

好抓!标记它你会怎么做,直到枚举才会被执行。 – RollemIra

回答

2

有一些过程将在EF中如何运作。

  1. 查询只在这一点上,整个查询将在您的上面的例子中被执行
  2. 延迟加载只影响导航属性上枚举执行(这有时称为查询物质化)。 where语句的结果集将一次性下拉。

那么这意味着什么,你的情况:

//nothing happens here you are just describing what will happen later to make the 
// query execute here do a .ToArray or similar, to prevent people adding to the sql 
// resulting from this use .AsEnumerable 
IQueryable<EntityA> collection = context.EntitiesA.where(<condition>); 
//when it first hits this foreach a 
//SELECT {cols} FROM [YourTable] WHERE [YourCondition] will be performed 
foreach (EntityA entity in collection) 
{ 
    //data here will be from the point in time the foreach started (eg if you have updated during the enumeration in the database you will have out of date data) 
    // do some stuff 
} 
0

如果你真的担心这可能会发生,然后得到的ID前面的列表,并为每个新DbContext单独处理它们(或者说在每批10个之后)。就像:

IList<int> collection = context.EntitiesA.Where(...).Select(k => k.id).ToList(); 
foreach (int entityId in collection) 
{ 
    using (Context context = new Context()) 
    { 
     TEntity entity = context.EntitiesA.Find(entityId); 
     // do some stuff 
     context.Submit(); 
    } 
} 
0

我认为你的问题的答案是'它取决于'。您正在描述的问题称为“不可重复读取”,可以通过设置适当的事务隔离级别来防止发生。但它带来了性能和潜在的僵局成本。

欲了解更多详情,您可以阅读this

+0

我不认为这是这里描述的问题,当atransaction回滚时发生不可重复的读取。这不是该操作所描述的。他对数据库更改时发生的情况感兴趣。他的实体是否能够立即反映这种变化呢? –