子记录的 LinqDataSource/ListView - 仅在保存包含记录时才保存?

发布于 2024-07-08 17:40:09 字数 1094 浏览 12 评论 0原文

我有一个用于编辑事件的表单,用户可以在其中 (a) 在 FormView 中编辑事件的详细信息(标题、描述、日期等),以及 (b) 查看和编辑联系人的 ListView注册参加该活动。

这是我的 LinqDataSource,它允许我向事件添加和删除联系人。

<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>

这工作得很好,但当然它会保留对数据库的更改; 并且它仅在事件已经创建时才有效。 理想情况下,我希望仅在 FormView 保存后才保留对 ListView 的更改(因此,如果有人对 ListView 进行了一些更改,然后取消了 FormView,则更改将被丢弃)。 同样,我希望能够一次性创建一个新活动、输入详细信息并让一些人报名参加; 当 FormView 保存时,它会获取事件的新 ID,然后 ListView 使用该 ID 进行保存。

在过去(Linq 之前),我使用自己广泛定制的 FormView 和 SqlDataSource 对象来完成此操作,这些对象负责临时保留数据更改、从 FormView 获取事件 ID 等。是否有更标准的方法使用 LinqDataSource 处理这种情况?

I have a single form for editing an event, in which the user can (a) edit the details of the event (title, description, dates, etc.) in a FormView and (b) view and edit a ListView of contacts who are registered for the event.

Here's my LinqDataSource, which allows me to add and remove contacts to the 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 fine, but of course it persists the changes to the database as they're made; and it only works when the event has already been created. Ideally, I'd like for my changes to the ListView to be persisted only once the FormView saves (so if someone makes some changes to the ListView and then cancels out of the FormView, the changes are discarded). Along the same lines, I'd like to be able to create a new event, enter its details, and sign some people up for it, all at once; when the FormView saves, it gets the new ID for the event, and then the ListView saves using that ID.

In the past (pre-Linq) I've accomplished this with my own extensively customized FormView and SqlDataSource objects, which take care of temporarily persisting the data changes, getting the event ID from the FormView, etc. Is there a more standard way of dealing with this scenario using the LinqDataSource?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不再见 2024-07-15 17:40:09

因此,您实际上希望将两个 LinqDataSource 包装在单个事务中。 有一种偷偷摸摸的方法可以利用 LinqDataSource 数据绑定和事件,并且仍然只进行一次提交。 使用此方法,您仍然可以使用动态数据、FormView、GridView、验证等。它仅依赖于挂钩到数据源。

示例标记:

<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!"/>

现在,在后面的代码中,您使用单个“提交”按钮来模仿 LinqDataSources 的行为。 您使用数据源插入项目,这会创建新对象,抓取该对象,然后对第二个对象再次执行此操作。 将这两个项目以及您想要的任何其他逻辑链接在一起,然后将其作为单个事务插入到数据库中。 关键是在插入事件中设置取消标志,以便数据源实际上不会插入到数据库中。

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();
    }
}

So effectively you want to wrap the two LinqDataSources in a single transaction. There is a sneaky way to leverage the LinqDataSource databinding and events and still do only one commit. Using this method you can still use Dynamic Data, FormView, GridView, validation, etc. It only relies on hooking into the 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 the single Submit button to mimic the behaviour of the LinqDataSources. You use the datasource to insert the item, which creates the new object, snaffle the object, do it again for the second object. Link the two items together and any other logic you want and then insert it into the database as a single transaction. The key is to set the Cancel flag in the Inserting event so that the datasource doesn't actually insert 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();
    }
}
冰魂雪魄 2024-07-15 17:40:09

表之间是否设置了外键?
如果这样做 - 那么在保存新事件列表时应该抛出异常。

关于主题,有一种方法可以以编程方式同时创建事件+列表记录。

但你必须编写一些代码。

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

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

列表项也一样。

ScottGu 的博客 LINQ 系列对此进行了明确描述

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

And on topic there is a way to create an event + list records at the same time programmaticaly.

but you will have 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 same for list items.

ScottGu's Blog LINQ series has this one described for sure

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文