2

我目前正在使用使用以下技术的项目。更新对象图时实体框架的断开行为

  1. ASP.net MVC - 表现层
  2. 数据服务层 - (WCF)
  3. 数据传输对象(DTO)与自动映射图层
  4. 领域层(POCO,代码第一次实体框架)
  5. 存储库层+实体框架4.3 + DbContext。

我们使用DTO将域对象反过来转换为使用自动映射器并通过使用WCF服务发送到前端。

另外,我们在WCF层为每个请求创建每个基于请求的DBContext,并且我们的WCF服务上下文由客户端DTO中的Per Call和No Tracking启用构建,并且完全断开连接。

另外我们有以下对象图。

public class User : BaseEntity 
    { 
     public virtual Identity Identity { get; set; } 

     public string UserName { get; set; } 

     public string Password { get; set; } 

     public int IdentityId { get; set; } 

     public virtual IList<Group> Groups{ get; set; } 
    } 



public class Identity : BaseEntity 
    { 
     public string FirstName { get; set; } 

     public string LastName { get; set; } 

     public virtual IList<Email> Emails { get; set; } 

     public virtual IList<PhoneNumber> PhoneNumbers { get; set; } 
    } 

我们的Dto结构与Domain相比更像。

我的问题:

当涉及到更新对象图,例如:UpdateUser两个(用户用户);实体框架的最佳方法是什么?

现在我们使用单一功能来保存导航数据例如:UpdateEmail(userId,Email)(仅保存原始数据而非关系);所以当我们考虑一个UnitOfWork时,它会在数据库中进行大量的插入和更新。

当前实现如下

public void UpdateUser(User user) 
    { 
    UpdateEmail(user.userId, user.Idenity.Emails); 
    UpdatePhone(user.userId, user.Identity.PhoneNumbers); 

    etc............. 

    UpdateUser(user); 
    UnitOfWork.Commit();// Calling DbContext.SaveChanges(); 
    } 

有,我们可以在上述情况与实体框架使用与断开连接的对象图中的任何模式或最佳实践?

+0

非常好是您的问题,现在你使用EF,它会提供更多的电话号码?由于您的电话号码和电子邮件是单独的表格,因此我无法在此找到解决办法。您可以为用户创建一个扁平化的实体,其中包含每个实体的五个并映射到插入的proc。它会减少呼叫,但不是最干净的恕我直言。如果您一次处理多个用户,那么可能会分解UOW以仅为每个用户执行操作,这样您的交易就会更短。目前是否存在性能问题或仅仅是未来的问题? –

+0

现在我们没有太多性能问题。但是,由于许多更新都发生在同一个函数中,所以存在一些锁定问题。奉承不是一种选择,因为我们正在将其作为域驱动设计。 – marvelTracker

+0

添加下面作为建议的答案与反馈。 –

回答

7

解决它的方法并不多。 EF doesn't have any direct suppor t用于更新断开连接的对象图。你必须编写你的更新逻辑,一般有两种方法如何做到这一点:

  • 当收到服务请求您将调用数据库,并获取当前数据库状态=用户与所有受影响的关系,更新的用户。您将使用数据库版本和更新版本来构建有效的更改集,因此最终EF将更新,插入和删除仅有真正更改的数据。
  • 您将修改您的DTO以将其运输状态以及您的客户将负责设置他在DTO上所做的修改类型。您将使用此信息为每个收到的实体正确配置ChangeTracker
+0

如果我们考虑选项01.所以这意味着例如:一对多的情况下,我们必须通过使用dbstate和update状态来操作集合来手动处理它。这是一种榛子:(不是吗?) – marvelTracker

+0

是的,你必须但很明显,如果你手动处理SQL,你也必须这样做,你想在DTO中没有状态的情况下完全断开连接的情况=你必须以某种方式确定什么已经改变,以知道应该使用什么样的SQL命令 –

+0

我相信,EF更改跟踪器(在dbcontext范围内)跟踪与给定的主键与自动映射器更新的断开连接的实体会更有帮助,它应该是一种将这些断开连接的实体重新关联到DbContext的方法。 – marvelTracker

0

现在您的问题是您使用EF并且它提出了很多更新要求?由于您的电话号码和电子邮件是单独的表格,因此我无法在此找到解决办法。您可以为用户创建一个扁平化的实体,其中包含每个实体的五个并映射到插入的proc。它会减少呼叫,但不是最干净的恕我直言。如果您一次处理多个用户,那么可能会分解UOW以仅为每个用户执行操作,这样您的交易就会更短。目前是否存在性能问题或仅仅是未来的问题? -

没有压扁你没有不同的情况比不使用EF。我不明白为什么这么想,因为你使用的是DDD,你不能引入特定于数据映射的实体。你的实体仍然可以使用,你只是另外有一个新的映射实体。事实上,你可以做到这一点没有在你的仓库后实体(资料库查询更改的对象,变平,并发送至数据访问层调用PROC)