简体   繁体   English

实体框架 - 保存对分离状态中相关对象的更改

[英]Entity Framework - Saving Changes to Related Objects in Detached State

I'm using the Northwind database as an example for this post where I am having a problem saving detached entities back to the database using the entity framework. 我正在使用Northwind数据库作为这篇文章的一个例子,我在使用实体框架将分离的实体保存回数据库时遇到了问题。

I have the following two methods to get me the territories and the regions: 我有以下两种方法来获取地区和地区:

    static List<Region> GetRegions()
    {
        using (NorthwindEntities entities = new NorthwindEntities())
        {
            entities.Region.MergeOption = System.Data.Objects.MergeOption.NoTracking;
            return entities.Region.ToList();
        }
    }

    static List<Territories> GetTerritories()
    {
        using (NorthwindEntities entities = new NorthwindEntities())
        {
            entities.Territories.MergeOption = System.Data.Objects.MergeOption.NoTracking;
            return entities.Territories.ToList();
        }
    }

These methods both work fine and get me the collection of objects I require in the detached state. 这些方法都工作正常,让我在分离状态下获得我需要的对象集合。

I also have a static method called SaveEntity, which takes in both an old entity and the currently editted entity, this is as follows: 我还有一个名为SaveEntity的静态方法,它接受旧实体和当前编辑的实体,如下所示:

    static void SaveEntity(EntityObject oldEntity, EntityObject newEntity)
    {
        using (NorthwindEntities entities = new NorthwindEntities())
        {
            entities.Attach(oldEntity);
            entities.ApplyPropertyChanges(newEntity.EntityKey.EntitySetName, newEntity);
            entities.SaveChanges();
        }
    }

This method partially works where the changes to the object are saved down to the database, but any changes to the relationship of related objects are not saved. 此方法部分适用于将对象的更改保存到数据库的位置,但不保存对相关对象关系的任何更改。

I have the following code calling the above methods as my example: 我有以下代码调用上面的方法作为我的例子:

            List<Territories> territories = GetTerritories();
        List<Region> regions = GetRegions();

        Region region = regions.Where(n => n.RegionID == 2).FirstOrDefault();
        Territories oldTerritory = territories.Where(n => n.TerritoryID == "01581").FirstOrDefault();
        Territories newTerritory = ObjectCopier.Clone<Territories>(oldTerritory);

        newTerritory.TerritoryDescription = "Hello World";
        newTerritory.Region = region;

        SaveEntity(oldTerritory, newTerritory);

The change to TerritoryDescription is successfully saved, but the change to Region is not, in the database it still remains as RegionID=1 instead of RegionID=2. 对TerritoryDe​​scription的更改已成功保存,但对Region的更改不是,在数据库中它仍然保留为RegionID = 1而不是RegionID = 2。

Can anyone provide me with some insight to why ApplyPropertyChanges doesn't propogate changes to related objects? 任何人都可以向我提供一些见解,说明为什么ApplyPropertyChanges不会传播对相关对象的更改?

Also, does anyone know of how I can get around this problem? 另外,有谁知道如何解决这个问题?

Instead of fetching regions and territories seperately, fetch both of them in the same query. 不是单独获取区域和区域,而是在同一查询中获取它们。 Something like (I assume you want to update the entity, do not want to create a new one); 类似的东西(我假设您想要更新实体,不想创建新的实体);

static List<Region> GetTerritoriesWithRegions()
    {
        using (NorthwindEntities entities = new NorthwindEntities())
        {
            entities.Territories.MergeOption = System.Data.Objects.MergeOption.NoTracking;
            return entities.Territories.Include("Region").ToList();
        }
    }

Then update them as the following; 然后将它们更新为以下内容;

   List<Territories> territoriesWithRegions = GetTerritoriesWithRegions();
        Territories territory = territories.Where(n => n.TerritoryID == "01581").FirstOrDefault();
        territory.TerritoryDescription = "Hello World";
        Region region = territories.Where(p => p.Any(q => q.Region.RegionID == 2)).FirstOrDefault().Region;
        territory.Region = region;

        SaveEntity(territory);

And save them; 并拯救他们;

static void SaveEntity(EntityObject entity)
    {
        using (NorthwindEntities entities = new NorthwindEntities())
        {
            entities.Attach(entity);
            entities.Context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);            
            entities.SaveChanges();
        }
    }

I have coded this on notepad so there may be mistakes; 我在记事本上编码了这个,所以可能有错误; if any please comment so I will update accordingly. 如果有的话请评论,所以我会相应更新。

I think you can find answers here (Alex James is better one). 我想你可以在这里找到答案(亚历克斯詹姆斯更好)。 Entity Framework Updating with Related Entity 使用相关实体更新实体框架

Basically, the reason is because in EF relationships are objects too and have statuses like entities (deleted, added,...), so you would need to have the original reference value in the context as well. 基本上,原因是因为在EF关系中也是对象,并且具有像实体(删除,添加,......)这样的状态,因此您还需要在上下文中具有原始引用值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM