我使用的实体框架的第一个代码和揭露罗斯文数据库通过WCF其余HTTP接口。

我不暴露OrderDetails表(以项目),因为它没有意义的创建以及随后加入的每一个需要OrderDetail单独通过的另一个服务。我的头脑也需要原子交易,无论是成功还是失败为一体。因此,包括我的顺序。OrderDetails收集当传递给客户和假设我要得到一个订单时创建或更新。

该问题,然而似乎是检测变化OrderDetails收集当重新连接了实体进行更新。令本身可作修改,以更新这些属性,但这并不级联到OrderDetail项目。所以我可以手动去通过设置更新的修改,但问题在于找出哪些是更新放在第一位。设置一个新的OrderDetail以修改将会引起错误的时候试图保存。

我读了一项建议设置Id的新的集合项目0和在服务器的使用,决定它是否是新的或现有的。罗斯文,但是使用了复合的关键之间订单id和ProductID为OrderDetails.这些都将必须由客户,所以我不能找到一种方法以检测是什么新的。此外,删除OrderDetail不会存在的分离式的图表和我将需要找出什么样已经删除,并明确地将其删除。

任何建议,将不胜感激。

public override Order Update(Order entity)
{
    dbset.Attach(entity);
    DataContext.Entry(entity).State = EntityState.Modified;

    foreach (var orderDetail in entity.OrderDetails)
    {
        DataContext.Entry(orderDetail).State = EntityState.Modified;
    }

    return entity;
}
有帮助吗?

解决方案

这个是 共同的和复杂的问题 没有魔法,这将为你做它。我的解决方案(和唯一一个其工作所有方案)是要加载 Order 再次更新的方法和手工合并的变化:

public override Order Update(Order entity)
{
    // No attach of entity

    var attached = DataContext.Orders.Include(o => o.OrderDetails).SingleOrDefault(...);
    if (attached == null) ...

    // Merge changes from entity to attached - if you change any property
    // it will be marked as modified automatically

    foreach (var detail in attached.OrderDetails.ToList())
    {
        // ToList is necessary because you will remove details from the collection

        // if detail exists in entity check if it must be updated and set its state

        // if detail doesn't exists in entity remove if from collection - if it is \
        // aggregation (detail cannot exists without Order) you must also delete it 
        // from context to ensure it will be deleted from the database
    }

    foreach (var detail in entity.OrderDetails)
    {
        // if it doesn't exists in attached create new detail instance,
        // fill it from detail in entity and add it to attached entity - 
        //you must not use the same instance you got from the entity
    }

    DataContext.SaveChanges();

    return entity;
}

有可能也需要手动检查的时间戳如果使用他们。

替代方案是什么你有描述0用于新的细节和负ID删除的详细信息,但是逻辑,必须在客户。它还工作只有在某些情况下。

其他提示

我最近一直允许开放源码的一些工作我为我的雇主一段时间以前(与一些改变的然)。实际上我写了一个扩展方法来解决这个问题,你可以在 http://refactorthis.wordpress.com/2012/12/11/introducing-graphdiff-for-entity-framework-code-first-allowing-automated-updates-of-a-graph-of-detached-entities/

希望它能帮助!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top