LinqDataSource / ListView for child records - only persist when the saved record is saved?

I have one form to edit an event where a user can (a) edit event details (title, description, dates, etc.) in a FormView and (b) view and edit a ListView of contacts registered for an event.

Here's my LinqDataSource that allows me to add and remove contacts to an event.

<asp:linqdatasource runat="server" id="ContactsDatasource" contexttypename="Db" tablename="ContactsCalendarEventsXtabs" autogeneratewhereclause="true" enabledelete="true" enableinsert="true">
    <whereparameters>
        <asp:querystringparameter name="CalendarEventID" querystringfield="id" type="Int32" />
    </whereparameters>
    <insertparameters>
        <asp:querystringparameter name="CalendarEventID" querystringfield="id" type="Int32" />
    </insertparameters>
</asp:linqdatasource>

      

This works great, but of course it saves changes to the database as they are created; and it only works when the event has already been created. Ideally, I would like my changes to the ListView to persist only after the FormView is saved (so if someone makes some changes to the ListView and then cancels the FormView, the changes are discarded). Along the same lines, I would like to be able to create a new event, enter its details and sign some people for it, all at once; when the FormView saves, it gets a new ID for the event, and then the ListView stores that ID.

In the past (pre-Linq) I have accomplished this with my own highly customizable FormView and SqlDataSource objects that take care of temporarily saving data changes, getting event ID from FormView, etc. Is there another standard way to deal with this scenario using LinqDataSource?

0


source to share


2 answers


Thus, you want to combine two LinqDataSources into one transaction. There is a hidden way to use LinqDataSource binding and binding events and still only have one commit. Using this method, you can still use Dynamic Data, FormView, GridView, validation, etc. It only relies on connecting to data sources.

Example markup:

<FormView>...</FormView>
<ListView>...</ListView>
<LinqDataSource ID="dsEvent" ...> </LinqDataSource>
<LinqDataSource ID="dsContact" ...> </LinqDataSource>
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit it All!"/>

      



Now, in the code behind, you are using a single Submit button to mimic the LinqDataSources behavior. You are using a datasource to insert an item that creates a new object, a snaffle object, repeat it for the second object. Link the two items together and whatever other logic you want, then insert into the database as one transaction. The key is to set the Cancel flag on the Insert event so that the data source is not actually inserted into the database.

protected void btnSubmit_Click(object sender, EventArgs e)
{
    Event evt = null;
    Contact contact = null;

    dsEvent.Inserting += (o,ea) => { evt = (ea.NewObject as Event); ea.Cancel = true; };
    dsEvent.InsertItem(true);
    dsContact.Inserting += (o, ea) => { contact = (ea.NewObject as Contact); ea.Cancel = true; };
    dsContact.InsertItem(true);

    evt.Contacts.Add(contact);

    using (var dbContext = new ContactsCalendarEventsXtabs())
    {
        dbContext.Events.InsertOnSubmit(evt);
        dbContext.SubmitChanges();
    }
}

      

+1


source


Do you have a foreign key between tables? if you do - then it should throw an exception when saving the list for a new event.

And on the topic there is a way to create + event list entries at the same time programmatically.

but you will need to write some code.



create all list items programmaticaly.
create event proggramaticaly.
event myevent = new event();
event.someprop = zzxxx;

link them programmaticaly.
then use  yourdatacontext.events.InsertOnSubmit(event);

      

and for list items.

ScottGu Blog The LINQ series accurately describes this

0


source







All Articles