开发者

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.

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:

    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();
  开发者_如何学C      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.

Can anyone provide me with some insight to why ApplyPropertyChanges doesn't propogate changes to related objects?

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜