0

I have a database with two tables in one to many relationship. Father(FatherId) and Child(ChildId, FatherId). I have created entity framework entities for those two tables.

Those two tables are populated with some values in correct relationships. From time to time I do an update synchronization from outside data source. What I need is to refresh all the children for father. Some are added, some are removed.

One particular case is a cause of grief. Lets say that a father has children [A,B,C] and imported data for that same father has children [B,C,D]. I have found that a child A is not removed from database which causes data corruption. Although I have correctly populated the father.Childs collection. I have come up with a workaround which I find cumbersome. Explained in the code below.

    private void InsertOrUpdate(Father father)
    {
        var id = father.FatherId;
        if (mContext.Fathers.Any(f => f.FatherId == id))
        {
            mContext.Fathers.Attach(father);
            mContext.ObjectStateManager.ChangeObjectState(father, EntityState.Modified);
        }
        else
        {
            mContext.Fathers.AddObject(father);
        }
    }


    // this method syncronizes outer data wtih DB
    private void handleFather(Result.Product resultProduct, ref int gtinCnt)
    {
            Father father= new Father();
            father.FatherId = ImportedData.FatherId;     // data form outer source
            Father.other data = ImportedData.otherdata; // some other stuff not important
            InsertOrUpdate(father);
            // father should be attached now
            // Because it does not correctly synchronize missing children (which are absent in outer data) I have to remove them "manualy"
            // This is the cumersome bit. I do not like I have to delete all Childs by myself. Why cannot entity framework correctly update DB from Father.Childs collection.
            foreach (var child in father.Childs.ToList()) 
                mContext.Childs.DeleteObject(child);
            mContext.SaveChanges();
            // Now, that I have deleted allChilds I can add them again form outer source
            foreach (OuterDataChild c in Outerdata) {
                 Child child = new Child();
                 child.Id = Id; // from outer source
                 child.FatherId = father.FatherId;
                 father.Childs.Add(child);
            }
            mContext.SaveChanges();
        }
    }

As you can see my workaround was to "manually" delete all the Childs for a Father, SaveChanges() to database. And then add all the Childs form outer source to collection and the SaveChanges() again. What I don like is that in essence I must take care of correct data synchronization, which sort of defetas the purpose of entity framework. I do not like deletion part. Is there an elegant alternative to my workaround?

f470071
  • 1,382
  • 3
  • 14
  • 30
  • Checkout this answer: http://stackoverflow.com/questions/7968598/entity-4-1-updating-an-existing-parent-entity-with-new-child-entities – Amanvir Mundra Apr 28 '17 at 07:15
  • @AmanvirSinghMundra This is exactly what I am doing right now and I am not satisfied with this approach. It is not elegant. – f470071 Apr 28 '17 at 07:17
  • I believe you are doing the first approach - the brute force one. Did you check the second approach mentioned in the answer. – Amanvir Mundra Apr 28 '17 at 07:19
  • @AmanvirSinghMundra Yes. I did check it. In fact I was toying with that idea also. But there is an in issue that for each ingredient there is a query to check if it still exists. I would have to check via if this is an actual DB query. In that case there is no gain. But I see other people revolve around same problem as I do. – f470071 Apr 28 '17 at 07:48
  • You can query all the ingredients/children in a single DB call and then do the checking in memory. – Amanvir Mundra Apr 28 '17 at 07:50

0 Answers0