实体框架4.1:如何处理每个呼叫的生命周期数据上下文? [英] Entity Framework 4.1: how to work with per call life time data context?

查看:139
本文介绍了实体框架4.1:如何处理每个呼叫的生命周期数据上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据这个帖子,我每个通话使用数据上下文,所以在我的WCF服务的每个方法中,我使用一个使用块创建一个新的数据上下文。

According to this post, I am using a data context per call, so in each method of my WCF service, I use a using block to create a new data context.

但是我有一些疑问以这种方式工作。

But I have some doubts in the form to work in this way.

例如,我使用一个来自我的存储库的方法getAllCLients()来获取数据库的所有客户端,然后服务发送到客户端将该方法与所有客户端调用列表。然后用户修改其中的一些信息,例如三个。修改客户端也许我可以添加到具有修改的客户端的列表。

For example, I use a method getAllCLients() from my repository to get all the clients of the data base, then the service send to the client that call the method a list with all the clients. Then the user modify the information of some of them, three for example. The modify client perhaps I can add to a list that have the modified clients.

当我想更新这三个客户端时,我可以调用一个方法updateClients()修改的客户端列表。我如何使用每个方法的新数据上下文,在updateCients()获取一个新的dataContext,没有实体,所以我认为我必须按照这些步骤:

When I want to update this three clients, I can call a method updateClients() which receive a list of modified clients. How I am use a new data context per each method, in updateCients() get a new dataContext, without entities, so I think that I have to follow this steps:

1.创建一个新的数据上下文,其中有要更新的客户端。所以我需要指定的条件。这是一个额外的操作(我得到客户端之前的getAllClients()方法),所以我需要再次获得客户端。

1.- create a new data context which has the clients that I want to update. SO I need to specified the conditions for that. This is an extra operation (I get the clients before with the getAllClients() method), so I need to get again the clients.

2.-抛出客户端收集DBSet(我使用EF 4.1)并更改信息。这样我就可以抛出我从客户端应用程序中收到的列表。所以我必须去扔两个名单。这需要资源。

2.- go throw the clients collection of the DBSet (I use EF 4.1) and change the information. This makes me to go throw the list that I receive from the client application too. So I must to go throw two lists. This needs resources.

3.-保存更改。这是需要的,所以它不需要更多的工作。

3.- save the changes. This is needed anyway, so it has no required more work.

有什么办法使步骤2容易吗?在dataContext中存在一些将数据从我修改的客户端传递到数据上下文中的客户端的方法?我使用POCO实体,也许它存在一个简单的方法。

There is any way to make the step 2 easily? exist some method in dataContext to pass the values from my modified client to the client in the data context? I use POCO entities, perhaps it exists an easy way to do that.

其他问题是关于并发。如果我使用允许EF(具有时间戳字段)的比喻并发来控制并发,最好是为每个客户端调用updateClient(),或者更好地传递与所有客户端的列表?我的意思是,如果我使用列表作为参数,如果一个客户端出现并发问题,例如第二个客户端将正确更新,但第二个客户端也不会更新。如何向用户通知某些客户端有问题?

Other question is about concurrency. If I control the concurrency with pesimistic concurrency that allow EF (with a timestamp field for example), is it better to call the updateClient() one for each client or better to pass a list with all the clients? I mean that if I use a list as parameter, if there is a concurrency issue with one client,the second for example, the first client will be update correctly, but the second not and the third neither. How can I notify to the user that there is problems with some clients?

要恢复,我想知道在短暂的生活中进行更新的最佳方法数据文本。

To resume, I would like to know the best way to make updates when I have a short life datacontext.

谢谢。
Daimroc。

Thanks. Daimroc.

推荐答案

服务是断开连接的情况,所以当客户端传回你只需要处理的修改记录如修改。您不需要从数据库中加载所有记录。

The service is disconnected scenario so when your client passes backs modified records you just need to process them as modified. You don't need to load all records from database for that.

public void SaveClients(List<Client> modifiedClients)
{
    using (var context = new Context())
    {
        modifiedClients.ForEach(c => 
           {
               context.Entry(c).State = EntityState.Modified;
           });
        context.SaveChanges(); 
    }
}

如果您正在使用每个呼叫服务和每个服务操作需要上下文,您可以将上下文实例移动到服务构造函数,因为服务实例将仅生效到服务器单服务调用=您不需要使用为每个调用。如果你这样做不要忘记在你的服务上实施 IDisposable 来处理上下文。

If you are using per call service and every service operation needs context you can move your context instancing to service constructor because service instance will live only to server single service call = you don't need using for every call. If you do that don't forget to implement IDisposable on your service to dispose context.


另一个问题是并发问题。如果我使用
pesimistic并发控制并发,允许EF(时间戳字段为
示例),最好是为每个客户端调用updateClient()一个
或更好地传递列出所有客户端?

Other question is about concurrency. If I control the concurrency with pesimistic concurrency that allow EF (with a timestamp field for example), is it better to call the updateClient() one for each client or better to pass a list with all the clients?

EF不支持开箱即用的复杂的并发。使用时间戳是乐观的并发性,因为它允许其他人使用记录。 Pesimistic并发性是应用程序逻辑,其他客户端无法选择锁定记录进行更新。

EF doesn't support pesimistic concurrency out of the box. Using timestamp is optimistic concurrency because it allows others to use the record. Pesimistic concurrency is application logic where other client is not able to select locked record for update.

并发解析每个记录,但这种情况下的问题是事务。每次调用 SaveChanges 导致用于处理数据库中所有更改的事务。因此,如果任何修改的记录不是最新的,您将获得并发异常,并且整个事务被回滚=没有更新记录。

The concurrency is resolved per record but the problem in this case is transaction. Each call to SaveChanges results in transaction used to process all changes in the database. So if any of your modified records is not up to date you will get concurrency exception and whole transaction is rolled back = no record is updated.

您仍然可以通过将修改的记录列表传递到服务来克服这个问题(减少客户端和服务之间的往返是最佳做法),但是您可以分别处理每个记录为每个记录调用 SaveChanges 。无论如何,这应该非常仔细考虑,因为每次调用 SaveChanges 就像单独的工作单位 - 这真的是你想要的吗?

You can still overcome the issue by passing list of modified records to the service (reducing roundtrips between client and service is a best practice) but you can process each record separately by calling SaveChanges for every single record. Anyway this should be very carefully considered because each call to SaveChanges is like separate unit of work - is it really what you want?

Btw。最好的做法是使你的服务无国界。你应该避免维护服务电话之间的数据,这个例子真的不需要它。

Btw. the best practice is to make your service statless. You should avoid maintaining data between service calls and this example really doesn't need it.

这篇关于实体框架4.1:如何处理每个呼叫的生命周期数据上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆