【问题标题】:Best practice for updating related entities in ASP.NET MVC + EF4 without loading entity first在 ASP.NET MVC + EF4 中更新相关实体而不首先加载实体的最佳实践
【发布时间】:2011-05-15 08:46:05
【问题描述】:

我看到了一些与主题相关的问题,但找不到此场景的答案。

我的结构类似于

我的控制器的一部分

//
// GET: /Person/Edit/5

public ActionResult Edit(int id)
{
    var viewModel = new PersonViewModel(PersonRepository.Get(id));
    return View(model);
}

//
// POST: /Person/Edit

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(PersonViewModel model)
{
    PersonRepository.Update(model.Person, model.Phones);
    return RedirectToAction("Index");
}

在我的存储库中,我正在做这样的事情:

public void Update(Person person, ICollection<Phone> phones)
{
    using (var unitOfWork = UnitOfWork.Current)
    {
         Attach(contact);
         UpdatePhones(contact, phones);
         unitOfWork.Commit();
    }
}
public Person Attach(Person person)
{
     Context.AttachTo("Persons", entity);
     Context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
     return entity;
}
public void UpdatePhones(Person person, ICollection<Phone> phones)
{
    if (phones == null || phones.Count == 0) return;
    foreach (var phone in phones.Where(o => o.IsDeleted && !o.IsNew))
    {
         PhoneRepository.Delete(phone);
    }
    foreach (var phone in phones.Where(o => !o.IsDeleted && o.IsNew))
    {
         party.Phones.Add(phone);
    }
    foreach (var phone in phones.Where(o => !o.IsDeleted && !o.IsNew))
    {
         phone.PartyID = party.ID;
         PhoneRepository.Attach(phone);
    }
}

IsDeleted 和 IsNew 不会持久化到 db 中并以动态形式使用。 PhonesRepository Attach() 是一样的。

我这样做是因为我需要尽可能减少数据库调用的数量。也许有一个已知的最佳实践?

谢谢=)

【问题讨论】:

    标签: .net asp.net-mvc asp.net-mvc-2 orm entity-framework-4


    【解决方案1】:

    这还不错。与我们的设置非常相似。

    几个指针:

    1 - 为您的存储库使用泛型。您的 Attach 代码非常简单,不需要在实体之间重复。如果您创建了GenericRepository&lt;T&gt;,那么您的附加代码将是:

    public T Attach<T>(T entity) where T : class
    {
         Context.GetEntitySet<T>.Attach(entity); // pluralization on (typeof)T.name to get entity set
         Context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
         return entity;
    }
    

    2 - 我会将UpdatePhones 方法分成单独的方法。我不会依靠标志(IsDeleted 等)来确定行动方案。我会更明确。

    3 - 看起来你有一个PhoneRepository?为什么? Person 是您的聚合根,Phone 始终与特定的 Person 相关,因此您应该在此聚合边界中只包含 PersonRepository。您应该附加到特定人的Phones ObjectSet`。

    顺便说一句 - 我假设您禁用了 延迟加载?否则,ICollection 上的那些 LINQ 操作将导致静默往返。

    除了以上几点(主要与设计相关),优化方面你的代码对我来说看起来不错。

    最后一点 - 还有另一种推荐的技术 (Alex James) 用于在分离的上下文 (aka MVC) 中更新实体,称为“存根技术”。

    如果您有兴趣,我几天前问了一个问题(并自己解决了),check it out

    HTH。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-23
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      相关资源
      最近更新 更多