none
Assigning a parent child object automatically adds the record to the inserted changeset RRS feed

  • Question

  • Hi I have a purchaseOrders table with an association (1 to many) to a Projects table,

    [

    Association(Name="Projects_PurchaseOrderHeader_Working", Storage="_Projects", ThisKey="ProjectId", IsForeignKey=true)]

    When I create a new purchase order and assign it to a particular project,
    ex.
    PurchaseOrder newPO = new PurchaseOrder();
    newPO.Projects = datacontext.Projects.FirstOrDefault();

    on checking the inserted changeset I can see that the newPO has already been added to the inserted changeset. Is there any way to prevent this? Why is the PurchaseOrder already in the changeset, I have not called datacontext.PurchaseOrders.InsertOnSubmit(newPO); I have not specified in any way that I want this newPO saved yet. All I did is created a new PO and said it belongs to a particular project.
    This is causing a problem for me because I can have a workflow which starts out at a Purchase order creation, may drill into creating some other items which can be saved but cancel out of creating the Purchase order.

    Here is the linq generated code for my association, the newPO becomes inserted into the inserted changeset with the following code line

    value

     

    .PurchaseOrderHeader_Working.Add(this);//here value is the project, this is the current purchase order

     



    [

    Association(Name="Projects_PurchaseOrderHeader_Working", Storage="_Projects", ThisKey="ProjectId", IsForeignKey=true)]

     

    public Projects Projects

    {

     

    get

    {

     

    return this._Projects.Entity;

    }

     

    set

    {

     

    Projects previousValue = this._Projects.Entity;

     

    if (((previousValue != value)

    || (

    this._Projects.HasLoadedOrAssignedValue == false)))

    {

     

    this.SendPropertyChanging();

     

    if ((previousValue != null))

    {

     

    this._Projects.Entity = null;

    previousValue.PurchaseOrderHeader_Working.Remove(

    this);

    }

     

    this._Projects.Entity = value;

     

    if ((value != null))

    {

     

    value.PurchaseOrderHeader_Working.Add(this);

     

    this._ProjectId = value.Id;

    }

     

    else

    {

     

    this._ProjectId = default(Nullable<int>);

    }

     

    this.SendPropertyChanged("Projects");

    }

    }

    }

     


    Thank you for any help on this, it seems like I should be able to control better when I want to save my object,

    Chris

    Wednesday, February 10, 2010 11:06 PM

Answers

  • Hello Chris,

     

    It is a designed behavior of LINQ to SQL.  We don’t need to call InsertOnSubmit on every entity to set their Inserted state.  Sometimes, setting the relationship with the existing entities can also make them as Inserted.  First, the PurchaseOrder object is new for the DataContext and has not been tracked.   But when it’s Projects property set to an existing entity of the DataContext, the new PruchaseOrder object needs to be automatically set a inserted since DataContext will also track its state.  Quote from the Inserting Objects section of Object States and Change-Tracking (LINQ to SQL):

     

    “You can explicitly request Inserts by using InsertOnSubmit. Alternatively, LINQ to SQL can infer Inserts by finding objects connected to one of the known objects that must be updated.”

     

    If you want to remove the inserted PurchaseOrder later, please try newPO.Projects = null;

     

    Does this work for you?  

     

    Have a nice day!

     

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by derski Thursday, February 11, 2010 6:42 PM
    Thursday, February 11, 2010 7:08 AM
    Moderator

All replies

  • Hello Chris,

     

    It is a designed behavior of LINQ to SQL.  We don’t need to call InsertOnSubmit on every entity to set their Inserted state.  Sometimes, setting the relationship with the existing entities can also make them as Inserted.  First, the PurchaseOrder object is new for the DataContext and has not been tracked.   But when it’s Projects property set to an existing entity of the DataContext, the new PruchaseOrder object needs to be automatically set a inserted since DataContext will also track its state.  Quote from the Inserting Objects section of Object States and Change-Tracking (LINQ to SQL):

     

    “You can explicitly request Inserts by using InsertOnSubmit. Alternatively, LINQ to SQL can infer Inserts by finding objects connected to one of the known objects that must be updated.”

     

    If you want to remove the inserted PurchaseOrder later, please try newPO.Projects = null;

     

    Does this work for you?  

     

    Have a nice day!

     

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by derski Thursday, February 11, 2010 6:42 PM
    Thursday, February 11, 2010 7:08 AM
    Moderator
  • Thank you for the reply,
    my problem is actually that the Purchase order gets saved when I don't want it to. Here is my case scenario, I create a new Purchase Order, this opens my Purchase order add / edit form, in the form I specify the Project this po belongs to and the Vendor this belongs to, this will mark the PO for insertion. Next from the PO add / edit form I want to add some items to the PO from to I enter my Vendor Products form to get a pick list of all items associated with a particual vendor. Suppose The vendor product has not been entered yet, I add a new vendor product and need to save it it so I call the submitChanges() after putting in my vendor product. At this point the PO will get saved which could be wrong becuase I may still decide to cancel the original PO but still want to save that vendor product.
    I guess I can deal with that in 2 different ways, first is to make sure I don't call submit changes when I decide to add the vendor product, this would be complicated for me because I can access this functionality from many different workflows, also it seems pretty logical that when the user chooses accept on a new vendor product it makes sense to save it at that point.
    The other approach is what I've opted to do now... if I leave my PO form to drill further into any workflows and the inserted changeset already contains my new PO I use the datacontext.purchaseorders.deleteonSubmit(newPO) to remove it from the change set, this way if anything gets saved in the meantime it will not contain my PO.
    When I finish up whatever I was doing and come back to the PO form, on closing if the user accepts to save I just make sure that PO gets manually reinserted back into the changeset by using the insertOnSubmit(newPO). It seems to work fine.

    I can understand why the new object would get added to the datacontext becuase it certainly needs to be tracked I"m not 100% sure if it makes to flag it for insertion just yet...maybe a different flag like pending insertion :) but anyways, I have a workaround to this, just thought maybe I was missing some setting somewhere where you could specify how linq2sql will treat new objects.
    Thank you again for your help.

    Chris
    Thursday, February 11, 2010 6:42 PM
  • My pleasure!  :)

    Have a nice weekend! 

     

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, February 12, 2010 1:35 AM
    Moderator