使用WCF和Entity Framework时,是否可以在客户端上存储ObjectContext?

时间:2010-03-21 12:18:54

标签: c# wcf entity-framework

我有一个WCF服务,它在我的数据模型上执行CRUD操作:添加,获取,更新和删除。我正在为我的数据模型使用Entity Framework。 另一方面,有一个客户端应用程序调用WCF服务的方法。

例如,我有一个Customer类:

[DataContract]
public class Customer
{
   public Guid CustomerId {get; set;}
   public string CustomerName {get; set;}
}

和WCF服务定义了这个方法:

public void AddCustomer(Customer c)
{
    MyEntities _entities = new MyEntities();
    _entities.AddToCustomers(c);
    _entities.SaveChanges();
}

并且客户端应用程序将对象传递给WCF服务:

var customer = new Customer(){CustomerId = Guid.NewGuid, CustomerName="SomeName"};
MyService svc = new MyService();
svc.Add(customer); // or svc.Update(customer) for example

但是当我需要将大量对象传递给WCF时,这可能是一个性能问题,因为我每次执行Add(),Update(),Get()或Delete时都需要创建ObjectContext ()。

我正在考虑的是将ObjectContext保留在客户端上,并将ObjectContext作为附加参数传递给wcf方法。

是否可以在客户端上创建并保留ObjectContext,并且不为每个操作重新创建它?如果不是,怎样才能加速将大量数据传递给wcf服务?

塞吉

3 个答案:

答案 0 :(得分:3)

不,无法通过WCF服务调用序列化ObjectContext。

当前版本的实体框架实际上并不支持像这样的n层应用程序。

我们有一个使用实体框架的n层应用程序,我们每次从ObjectContext分离我们的对象,并为每个调用重新创建和重新附加,它工作正常。执行重新创建似乎没有任何显着的性能成本(SQL服务器无论如何都会汇集数据库连接),因此除非您正在执行需要非常大的吞吐量的事情,否则不要进入过早优化。只是让它运行,然后对其进行分析。说实话,你最大的瓶颈将是WCF服务调用和网络上的数据传输,所以如果你想提高性能,最小化你传输的数据量而不是担心你的ObjectContext。或者您可以创建一个服务调用,该服务调用获取对象列表并同时将它们全部添加。

但是,EF4会更好地做到这一点。请查看this MSDN文章,了解有关EF4中n层支持的更多信息。如果您使用测试版或等待一个月的发布,可能值得一看。

答案 1 :(得分:2)

实体框架中的ObjectContext课程是围绕 Unit of Work 的概念设计的。其目的是跟踪对实体对象中包含的数据所做的一些更改,然后将这些更改作为批处理应用于基础数据库(通过ObjectContext.SaveChanges方法)。
工作单元很好 - 定义的边界,旨在持续一段有限的时间。在Entity Framework中,工作单元通过ObjectContext以这种方式实现:

using (var db = new ObjectContext()) // The unit of work starts with the constructor
{
    // perform work
} // The unit of work ends with the Dispose method

无论何时需要对数据库中的数据执行某些工作, ObjectContext都是为了创建和处理,因此它在这个意义上设计为轻量级。

话虽这么说,我不相信保持一个长期存在的ObjectContext实例将增加应用程序的性能。相反,它会导致ObjectContext实例在继续跟踪更多操作时占用更多内存。

如果您需要通过网络传输大量数据,那么您可以做的最好的事情就是使用快速轻量级的通信协议。在WCF中,您可以使用netTcpBinding,它通过TCP连接传输二进制格式的消息。重要的是要记住,只有在两端都使用.NET时,这才有效,因为使用的二进制格式特定于.NET。

答案 2 :(得分:0)

不,您不能将ObjectContext保留在客户端(以这种方式使用WCF会有什么问题?),但是您可以实现延迟更改以节省服务或创建方法AddCostumers(Customer [] customers)