更新对象图时实体框架的断开行为

时间:2012-06-18 06:53:11

标签: asp.net-mvc-3 wcf entity-framework-4.1 disconnected-environment

我目前正在使用一个使用以下技术的项目。

  1. ASP.net MVC - 表示层
  2. 数据服务层 - (WCF)
  3. 带有Auto Mapper的数据传输对象(DTO)层
  4. 域层(POCO,代码优先实体框架)
  5. 存储库层+实体框架4.3 + DbContext。
  6. 我们使用DTO使用自动映射器转换Domain对象,并使用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; }
        }
    

    与Domain相比,我们的Dto结构更加相同。

    我的问题:

    更新对象图时例如: UpdateUser(用户用户);实体框架的最佳方法是什么?

    现在我们使用单一功能保存导航数据ex: 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();
        }
    

    在断开对象图的上述情况下,我们可以使用Entity Framework进行任何模式或最佳实践吗?

3 个答案:

答案 0 :(得分:7)

解决它的选择并不多。 EF doesn't have any direct suppor用于更新断开连接的对象图。您必须编写更新逻辑代码,通常有两种方法:

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

答案 1 :(得分:6)

Julie Lerman在some video's

中解释得非常好

答案 2 :(得分:0)

现在您的问题是您使用EF并且它会进行大量的更新调用吗?由于您的电话号码和电子邮件是单独的表,我在这里看不到解决方法。您可以为用户创建一个展平实体,其中包含每个实例的五个,并映射到插入的proc。它会减少通话但不是最干净的恕我直言。如果您正在同时处理许多用户,那么可能会分解UOW以仅对每个用户执行操作,从而缩短交易时间。目前存在性能问题还是未来的问题? -

如果没有展平,你与没有使用EF的场景没有什么不同。我不明白为什么想到因为你使用DDD你不能引入特定于数据映射的实体。你的实体仍然可以使用,你只需要一个带有映射的新实体。事实上,您可以在以后没有存储库中的实体的情况下执行此操作(存储库查询已更改的对象,展平并发送到数据访问层以调用proc)