实体框架 - 分离更新问题

时间:2009-01-21 17:47:38

标签: c# entity-framework

好的,我正在尝试使用此自定义扩展来执行实体更新。现在它应该更新所有属性,然后更新所有相关的结尾(引用)。问题是即使具有更改的实体确实具有有效且正确的实体密钥的相关结尾(在调试器中验证它)。当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

感谢帮助。

更新: 这是更新方法

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 个答案:

答案 0 :(得分:1)

由于Detach在EF中的工作方式,这根本不可能。

我发现如果我自己添加了关键信息,我可以通过通用调用来保存它。

问题在于,在调用Detach之后返回实体的那一刻,您将丢失所有关系数据。我已经找到了一些关于为每个实体编写图形管理器的文章,但我发现作为EF的浪费,应该做这些事情(据说它将在v2中)。

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