none
Not able to insert Child record when Parent record is not modified. RRS feed

  • Question

  •  

    Hi,

     

    I have 2 tables in which I have specified relationship using AssociationAttribute. So my one table act as Parent Table and second table act as Child Table.

     

    Following scenario work:

     

    Step 1:  Retreive Parent record... This will also retrieve Child records.

     

    Step 2: Update Parent record i.e change any field of parent record

     

    Step 3: Create new child record and initialize it.

     

    Step 4: Add child record to child container (EntitySet) in Parent record

     

    Step 5: Call SubmitChanges on datacontext.

     

    After this parent record will be updated in Database and new record is inserted in child table in database.

     

     

    If I not perform Step 2, child record is not inserted in child table in database.

     

    Instead of inserting new child record, if I modified (update) exisitng child record without modifying Parent record then changes are reflected in Database properly.

     

    Have anybody face this problem?

     

    Thanks & regards,

    Rakesh Patel.

    Tuesday, June 10, 2008 6:48 AM

Answers

  • Adding a child object to the parent's collection should be signalling to the parent (due to bi-directional references) and the parent should be notifying the DataContext that the parent is 'interesting' even though none of the fields are changed.  During SubmitChanges the DataContext should be looking for all new objects near the 'interesting' objects.  Of course, this relationship is tenuous and can be disturbed if you write your own objects instead of using the designer's codegen.

     

    To be certain that the DataContext will be aware of your new child instance, you can tell it directly with the InsertOnSubmit method.

     

    db.ChildTable.InsertOnSubmit(newChildInstance);

     

     

     

    Tuesday, June 10, 2008 3:08 PM
    Moderator

All replies

  • Hi Rakesh,

     

    In order to preserve the relations, Linq to SQL needs the parent attached to the context as well. You can attach parent to the context as unmodified, and parent won't be updated.

     

    You can do that so through an overload of Attach(entity, isModified) and pass ismodified false(which is default). Your code will look like this in the end:

    Code Snippet

     

    context.Parents.Attach(entity.Parent, false);

     

    ,,,, // do what you need

    context.SubmitChanges();

     

     

    Hope this is what you wanted. If it doesn't work, a code sample that doesnt work would be good.

     

    Sidar

     

    Tuesday, June 10, 2008 9:50 AM
  • Hi Sidar,

     

    I am retrieving Parent Object using LINQ's DataContext and using same DataContext to save the information.

     

    So my parent object is already attached to DataContext and its ObjectTrackingEnabled is set to true. So any changes I do on objects that are attached to DataContext will be recorded (tracked) by DataContext.

     

    Problem with attaching object as modified is that DataContext will not have information about changes done on Object and so it will try to update all fields in database.

     

     

     

    Here is the mapping code in master table..

     

           

    Code Snippet

    private EntitySet<ChildTable> _ChildTableList;

     

            [DataMember()]

            [Association(Storage = "_ChildTableList", ThisKey = "MasterTableID", OtherKey = "MasterTableID", Name = "ChildTable")]

            public EntitySet<ChildTable> ChildTables

            {

                get { return this._ChildTableList; }

                set { this._ChildTableList.Assign(value); }

            }

     

    // Constructor

    public MasterTable()

            {

                this._ChildTableList = new EntitySet<ChildTable>(new Action<ChildTable>(this.attach_ChildTable), new Action<ChildTable>(this.detach_ChildTable));

            }

     

    // Handler that will be called when child object is added to list (ChildTableList)

            private void attach_ChildTable(ChildTable entity)

            {

                entity.MasterTableObject = this;

            }

     

    // Handler that will be called when child object is removed from list (ChildTableList)

            private void detach_ChildTable(ChildTable entity)

            {

                entity.MasterTableObject = null;

            }

     

     

     

     

    Here is the mapping code in child table

     

           

    Code Snippet

    private EntityRef<MasterTable> _MasterTable;

     

            [DataMember()]

            [Association(Storage = "_MasterTable", ThisKey = "MasterTableID", OtherKey = "MasterTableID", Name = "ChildTable", IsForeignKey = true)]

            public MasterTable MasterTable

            {

                get { return this._MasterTable.Entity; }

                set

                {

                    MasterTable previousValue = this._MasterTable.Entity;

                    if (((previousValue != value) || (this._MasterTable.HasLoadedOrAssignedValue == false)))

                    {

                        if ((previousValue != null))

                        {

                            this._MasterTable.Entity = null;

                            previousValue.ChildTables.Remove(this);

                        }

     

                        this._MasterTable.Entity = value;

     

                        if (value != null)

                        {

                            value.ChildTables.Add(this);

                            this.MasterTableID = value.MasterTableID;

                        }

                        else

                        {

                            this.MasterTableID = default(long);

                        }

     

                        this._MasterTable.Entity = value;

                    }

                }

            }

     

     

     

    Here is code for retrieving and updating database:

     

    Code Snippet

    // Create new connection

    SqlConnection con = new SqlConnection("my valid database connection string");

     

    // Open connection

    con.Open();

     

    // create new data context

    DataContext dc = new DataContext(con);

     

    // retrieve data

    List data = dc.GetTable().ToList();

     

    // check data exist

    if (data != null && data.Count > 0)

    {

          // Udpate parent table .... Uncomment below line and this code will work.

          // data[0].SomeProperty = "New Value";

        

          // Create new child object

          ChildTable childObject = new ChildObject();

     

          //

          // Intialize child object code....

          //

     

          // add child object to parent

          data[0].ChildTables.Add(childObject);

     

          // submit changes.

         dc.SubmitChanges();

    }

     

     

     

    Rakesh Patel

    Tuesday, June 10, 2008 10:13 AM
  • Adding a child object to the parent's collection should be signalling to the parent (due to bi-directional references) and the parent should be notifying the DataContext that the parent is 'interesting' even though none of the fields are changed.  During SubmitChanges the DataContext should be looking for all new objects near the 'interesting' objects.  Of course, this relationship is tenuous and can be disturbed if you write your own objects instead of using the designer's codegen.

     

    To be certain that the DataContext will be aware of your new child instance, you can tell it directly with the InsertOnSubmit method.

     

    db.ChildTable.InsertOnSubmit(newChildInstance);

     

     

     

    Tuesday, June 10, 2008 3:08 PM
    Moderator