如何从不同的上下文中保存实体上的NavigationProperty?

时间:2011-09-20 20:01:25

标签: c# entity-framework savechanges navigation-properties

我有两个数据库表,一个用于事件,一个用于RecurrenceRules。事件的FK指向RecurrenceRuleID。

我想要做的就是从一个新的上下文中保存一个事件和它的重复规则,但我似乎无法实现这一点。我错过了什么?

using (var context = new ScheduledEventEntities())
{
    if (obj.EntityKey == null)
    {
        context.AddObject(obj.EntityKey.EntitySetName, obj);
    }
    else
    {
        var existingObject = context.Events.FirstOrDefault(p => p.Ident == obj.Ident);
        context.ApplyCurrentValues<Event>(obj.EntityKey.EntitySetName, obj);

        // How do I save obj.RecurrenceRule?
    }

    context.SaveChanges();
}

1 个答案:

答案 0 :(得分:2)

我会这样试试:

// ...
var existingObject = context.Events.Include("RecurrenceRule")
    .FirstOrDefault(p => p.Ident == obj.Ident);
context.ApplyCurrentValues<Event>(obj.EntityKey.EntitySetName, obj);

// 1st case: Relationship to RecurrenceRule has been removed or didn't exist
if (obj.RecurrenceRule == null)
    existingObject.RecurrenceRule = null;
// 2nd case: Relationship to RecurrenceRule must be set or updated
else
{
     // relationship has changed
    if (existingObject.RecurrenceRule == null ||
        obj.RecurrenceRule.Id != existingObject.RecurrenceRule.Id)
    {
        var existingRecurrenceRule = context.RecurrenceRule
            .SingleOrDefault(r => r.Id == obj.RecurrenceRule.Id);
        if (existingRecurrenceRule != null) // RecurrenceRule exists in DB
        {
            // Update scalar values
            context.ApplyCurrentValues<RecurrenceRule>(
               obj.RecurrenceRule.EntityKey.EntitySetName, obj.RecurrenceRule);
        }
        else // RecurrenceRule does not exist in DB
        {
            // nothing to do, SaveChanges will recognize new RecurrenceRule
            // and create INSERT statement
        }
        // set new relationship
        existingObject.RecurrenceRule = obj.RecurrenceRule;
    }
    else // same relationship: just update scalar values
    {
        // Update scalar values
        context.ApplyCurrentValues<RecurrenceRule>(
            obj.RecurrenceRule.EntityKey.EntitySetName, obj.RecurrenceRule);
    }
}

// ...

问题确实是ApplyCurrentValues只关心更新标量属性而不关心导航属性,所以你必须自己处理更新导航属性。 (遗憾的是,更新分离的对象图几乎总是导致这样繁琐的代码,因为实体框架中没有内置机制来为您完成此工作。)