none
Save Time problems/exceptions in Entity Framework RRS feed

  • Question

  • Hello All,

    We are using Entity Framework 4.0 in our WPF application. We have Model as show below

    We load the model using following line.

     

    using (var cotext = new LOB.Model.SavaBaseV1Entities())
                        {
                            _regressionModel = cotext.MV_MODEL_RegressionModel.Include("MV_RegressionModel_Indicators").Include("MV_RegressionModel_Indicators.MV_INDICATORS_Interpolated_FieldInfo").Where(mod => mod.RegressionID == vm.SelectedModelID).FirstOrDefault();
                        }


     

    Here one thing is important to mention that DBContext automatically close after loading Model as USING statement. After loading, we display Model properties in Textboxes and Indicator collection in Grid from where user can change some property of Model like "Name", "date" etc. Or can also Add/Remove/Update Indicators from Model.

    I have following code in SAVE command to persist user changes to database.

     

    using (var context = new LOB.Model.SavaBaseV1Entities())
                {                
                    if (add) //Here add mean, user does not load already saved model instead he created a new Model.
                    {
                         context.MV_MODEL_RegressionModel.AddObject(_RegressionModel);
                    }
                    else
                    {
                        context.Attach(_RegressionModel);
                        context.ObjectStateManager.ChangeObjectState(_RegressionModel, System.Data.EntityState.Modified);
                    }
    
                    foreach (LOB.Model.MV_RegressionModel_Indicators indicat in _RegressionModel.MV_RegressionModel_Indicators)
                    {
                        LOB.Model.MV_INDICATORS_Interpolated_FieldInfo finfo = indicat.MV_INDICATORS_Interpolated_FieldInfo;
                        if (finfo != null)
                        {
                            context.ObjectStateManager.ChangeObjectState(finfo, System.Data.EntityState.Unchanged);
                        }
                        if (!add) //In case of Add, as all Indicators will also need to be inserted so no need to change their status.
                        {
                            if(indicat.EntityState == System.Data.EntityState.Added)
                                context.ObjectStateManager.ChangeObjectState(indicat, System.Data.EntityState.Added);
                            else
                                context.ObjectStateManager.ChangeObjectState(indicat, System.Data.EntityState.Modified);
                        }
                    }
    //*************These are ference table for Model which does not have any change value so don't update these in database****//
     if(_RegressionModel.MV_Lookup_Values!= null) context.ObjectStateManager.ChangeObjectState(_RegressionModel.MV_Lookup_Values, System.Data.EntityState.Unchanged); if(_RegressionModel.MV_Lookup_Values1 != null) context.ObjectStateManager.ChangeObjectState(_RegressionModel.MV_Lookup_Values1, System.Data.EntityState.Unchanged); if (_RegressionModel.MV_Lookup_Values2 != null) context.ObjectStateManager.ChangeObjectState(_RegressionModel.MV_Lookup_Values2, System.Data.EntityState.Unchanged); if (_RegressionModel.MV_Lookup_Values2_1 != null) context.ObjectStateManager.ChangeObjectState(_RegressionModel.MV_Lookup_Values2_1, System.Data.EntityState.Unchanged); //**********************8End Reference tables***********************************// context.SaveChanges(); }

    In case of New Model (i.e. when add == true) then everything works fine here however in EDIT case, I am getting few exceptions. I noticed the few pattern like when user add a new Indicator in Model (Edit case) then following line throw an Exception "An object with a temporary EntityKey value cannot be attached to an object context."

     

    context.Attach(_RegressionModel);
                        <span style="color:red">context.ObjectStateManager.ChangeObjectState(_RegressionModel, System.Data.EntityState.Modified);</span>
    

    If use doesn't add new Indicator then this line of code works fine.

     

    Second Issue: After saving the Model using given above line of Code, Grid which are binded to list of Indicators, start throwing exception that  "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection." I again investigated the issue and find that following property in Model1.cs causing this exception.

     

    [XmlIgnoreAttribute()]
            [SoapIgnoreAttribute()]
            [DataMemberAttribute()]
            [EdmRelationshipNavigationPropertyAttribute("SavaBaseV1Model", "FK_MV_RegressionModel_Indicators_MV_INDICATORS_Interpolated_FieldInfo", "MV_INDICATORS_Interpolated_FieldInfo")]
            public MV_INDICATORS_Interpolated_FieldInfo MV_INDICATORS_Interpolated_FieldInfo
            {
                get
                {
                    return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<MV_INDICATORS_Interpolated_FieldInfo>("SavaBaseV1Model.FK_MV_RegressionModel_Indicators_MV_INDICATORS_Interpolated_FieldInfo", "MV_INDICATORS_Interpolated_FieldInfo").Value;
                    
                }
                set
                {
                    ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<MV_INDICATORS_Interpolated_FieldInfo>("SavaBaseV1Model.FK_MV_RegressionModel_Indicators_MV_INDICATORS_Interpolated_FieldInfo", "MV_INDICATORS_Interpolated_FieldInfo").Value = value;
                }
            }


    Third Issue: When user remove few Indicators from list then it does not remove in database even "SaveChanges" work successfully. How can I find & remove those indicators from Database?

    I am sure I will get response promptly as this is very urgent for me.

    Thanks,

    M. Irfan

     

     


    M. Irfan
    • Edited by M. Irfan Tuesday, October 11, 2011 10:42 AM Added more detail in comments form.
    Tuesday, October 11, 2011 10:33 AM

All replies

  • Hi,

    I think you can try to add .ToList() after your query result to get all records before the objectcontext disposed .

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Sunday, October 16, 2011 12:32 PM
    Moderator
  • Thank You Alan for your comments. I guess you try to address my SECOND Issue....right?

    I am loading a single object, not a list of objects. So does it make sense to use ".ToList()"??? Moreover my same code is working fine when I load object, but it give error after Saving Object to database.


    M. Irfan
    Monday, October 17, 2011 9:00 AM
  • Hi Irfan,

    Sorry for my wrong direction.

    1. The Attach exception: Adds an object to the ObjectContext and sets the object to the Unchanged state, An InvalidOperationException occurs when an object being attached has the same EntityKey as a different object already present in the object context. we can use ObjectManager.TryGetObjectStateEntry method to test if the object has existed. If yes, you can just to modify its value then savechanges.

    2. If you want to save new records to database, you just need to add the new instance of your Model(set the Indicators and Field Info) graph. EF will help you to add them all.

    3. If you want to remove the Indicator list, please don't remove it by you Model, it just sets the foreign key to null. you should remove it driectly from your objectContext.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, October 19, 2011 8:42 AM
    Moderator
  • Hello Alan,

    Thank you for your comments. I believe, again there is some misunderstanding.

    First Issue: My first issue was that when I came in Edit Mode (i.e. main object exist in database) however in its child list, I have added one new Child Object. Kindly note that if you see my above code sample then at save time, I already check that either it is "Add" mode or "Edit". In case of Add mode, I add object whereas in case of "Edit" I attach object.
    So in case of "Edit" main object exist but just added a new object in "MV_RegressionModel_Indicators" so this new child object is creating problem.

    Second Issue: Its related to using entity after saving it. Its not related to Save.

    Third Issue: If I don't remove it from my Model then how can I show it to user in my Grid, that these objects have been removed. As I said I have bind list of child objects with Grid. Now when user press "Delete" button on any row then I remove those object from my (in-memory) Entity Model object so that row should not appear in Grid. Now at the save time, I need to find those objects which user deleted so that I can also delete those from my database.

    I hope now I make things clear if there were any ambiguity.

    Kindly let me know your thoughts now.

    Thanks,
    M. Irfan


    M. Irfan
    Thursday, October 20, 2011 10:25 AM