2009-01-21 109 views
1

好吧,我正在尝试使用此自定义扩展来执行实体更新。现在它应该更新所有属性,然后更新所有相关的结束(引用)。问题在于,即使具有更改的实体确实具有有效且正确的实体密钥(在其调试器中验证)的相关结尾。当RelationshipManager获取它时,他们的键是空的。任何人看到这个代码有什么问题?实体框架 - 分离更新问题

public static void ApplyChanges(this ObjectContext context, EntityObject entityWithChanges) 
    { 
     if (entityWithChanges.EntityState == EntityState.Detached) 
     { 
      object entityCurrentlyInDB = null; 

      if (context.TryGetObjectByKey(entityWithChanges.EntityKey, out entityCurrentlyInDB)) 
      { 
       context.ApplyPropertyChanges(entityWithChanges.EntityKey.EntitySetName, entityWithChanges); 

       foreach (var relatedEnd in ((IEntityWithRelationships)entityCurrentlyInDB).RelationshipManager.GetAllRelatedEnds()) 
       { 
        var oldRef = relatedEnd as EntityReference; 

        if (oldRef != null) 
        { 
         var newRef = 
          ((IEntityWithRelationships)entityWithChanges).RelationshipManager 
          .GetRelatedEnd(oldRef.RelationshipName, oldRef.TargetRoleName) as EntityReference; 
         oldRef.EntityKey = newRef.EntityKey; 
        } 
       } 
      } 
      else 
      { 
       throw new ObjectNotFoundException(); 
      } 

     } 
    } 

这仅仅是一个修饰的我发现了什么 Here

感谢帮助版本。

UPDATE: 这是更新方法

public static void UpdateTemplate(Template template) 
    { 
     using (TheEntities context = new TheEntities()) 
     { 
      context.ApplyChanges(template); 
      try 
      { 
       context.SaveChanges(); 
      } 
      catch (OptimisticConcurrencyException) 
      { 
       context.Refresh(RefreshMode.ClientWins, template); 
       context.SaveChanges(); 
      } 

      context.RemoveTracking(template); 
     } 
    } 

这是单元测试:

[TestMethod] 
    public void CanUpdateATemplate() 
    { 
     Template template = new Template(); 
     template.Name = "Test"; 
     template.Description = "Test"; 

     TemplateType type = TemplateManager.FindTemplateTypeByName("Test"); 

     if (type == null) 
     { 
      type = new TemplateType(); 
      type.Name = "Test"; 
     } 

     template.TemplateType = type; 

     TemplateManager.AddTemplate(template); 

     template = TemplateManager.FindTemplateByID(template.TemplateID); 

     Assert.IsNotNull(template); 

     type = TemplateManager.FindTemplateTypeByName("Round"); 

     if (type == null) 
     { 
      type = new TemplateType(); 
      type.Name = "Round"; 
     } 

     template.TemplateType = type; 

     TemplateManager.UpdateTemplate(template); 

     template = TemplateManager.FindTemplateByID(template.TemplateID); 

     Assert.IsNotNull(template); 
     Assert.IsTrue(template.TemplateType.Name == "Round"); 

     TemplateManager.DeleteTemplate(template); 

     template = TemplateManager.FindTemplateByID(template.TemplateID); 

     Assert.IsNull(template); 
    } 

回答

1

这简直是不可能的,因为要分离工作在EF的方式。

我发现如果我自己添加了关键信息,我可以使通用调用工作,甚至保存它。

问题是,在你调用Detach之后返回实体的那一刻你就失去了所有的关系数据。我发现了一些关于为每个实体编写图形管理器的文章,但是我发现像EF这样的东西会浪费时间来做这件事(据说它会在v2中)。

EF尚未准备好进行N层部署。