使用Linq到SQL的分层数据绑定

时间:2009-07-03 14:31:57

标签: linq-to-sql data-binding gridview listview hierarchical-data

我正在尝试使用Linq To SQL的相当简单的数据绑定方案。

我有一个FacultyMembers表,其架构如下所示:

  • FacultyMemberID - int PK
  • 名称 - nvarchar
  • UniversityID - int FK to University table

等等。还有其他各种字符串属性。

我生成LTS DataClasses。我在一个页面上删除了一个LinqDataSource和一个GridView,为这两个启用了更新和删除,我正在以愉快的方式。没有代码,我可以更新我的字符串属性。使用UniversityID上的DropDownList进行一些操作,我也可以更新这种一对多的关系。耶。

现在,让我说我扔了一个多对多映射表。让我们说DivisionMemberships,它将FacultyMembers映射到Division。 DivisionMembership使用简单明了的模式:

  • FacultyMemberID - int PK,FK to FacultyMembers table
  • DivisionID - int PK,FK to Divisions表

现在,当我将一行GridView放入EditMode时,我遇到了一个问题,因为我不知道如何更新多对多关系。我用了几个替代方法,现在我正试图让ListView在那里工作。我正在做这样的事情:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    AllowPaging="True" AllowSorting="True" PageSize="25" DataKeyNames="FacultyMemberID" >
    <Columns>
        <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
        <asp:TemplateField HeaderText="University" SortExpression="UniversityID">
            <ItemTemplate>
                <asp:Label ID="Label1" runat="server" Text='<%# Eval("University.Name") %>' />
            </ItemTemplate>
            <EditItemTemplate>
                <asp:DropDownList ID="DropDownList2" runat="server" 
                    DataSourceID="LinqDataSourceUniversities" DataTextField="Name" 
                    DataValueField="UniversityID" SelectedValue='<%# Bind("UniversityID") %>'>
                </asp:DropDownList>
                <asp:LinqDataSource ID="LinqDataSourceUniversities" runat="server" 
                    ContextTypeName="NYDERHE.NYDERHEDataClassesDataContext" 
                    Select="new (UniversityID, Name)" TableName="Universities">
                </asp:LinqDataSource>
            </EditItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Division">
            <EditItemTemplate>
                <asp:ListView ID="ListView1" runat="server"
                    InsertItemPosition="LastItem" DataSource='<%# Eval("DivisionMemberships") %>'><ItemTemplate>
                        <li style="">FacultyMemberID:
                            <asp:Label ID="FacultyMemberIDLabel" runat="server" 
                                Text='<%# Eval("FacultyMemberID") %>' />
                            <br />
                            DivisionID:
                            <asp:Label ID="DivisionIDLabel" runat="server" 
                                Text='<%# Eval("DivisionID") %>' />
                            <br />
                            Division:
                            <asp:Label ID="DivisionLabel" runat="server" Text='<%# Eval("Division") %>' />
                            <br />
                            FacultyMember:
                            <asp:Label ID="FacultyMemberLabel" runat="server" 
                                Text='<%# Eval("FacultyMember") %>' />
                            <br />
                            <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" 
                                Text="Delete" />
                        </li>
                    </ItemTemplate>
                    </asp:ListView>
                </EditItemTemplate>

等等。上面的一些聊天被删除,但ListView非常详细,所以我不想重载页面。

此处需要注意的事项:

  • 对于我的大学协会,我使用新的LinqDataSource并查询大学ID匹配的项目,然后将新的UniversityID(DDL值)绑定到FacultyMember,而对于DivisionMemberships,我直接绑定到属性(如上所述{ {3}})
  • 我使用DataBinder。绑定()用于UniversityID,而我使用DataBinder。 Eval()用于DivisionMemberships。

如果我为DivisionMemberships切换到Bind(),我会得到EntitySet的NotSerializableException。如果我坚持使用Eval(),我必须自己编写ListView的OnDelete和OnInsert方法,并且我不想删除或插入DivisionMemberships,直到整个FacultyMember行退出EditMode。我可能会创建一个DataContext并将其粘贴在会话中,因为我没有其他方法来标记DivisionMemberships以进行更新。

我认为这个场景很容易开箱即用,但我迷路了。关于从哪里去的任何建议?具体来说,我是否应该与Bind()进行搏斗并尝试使EntitySet可序列化,我是否应该咬紧牙关并编写上面描述的用于在会话中存储DataContext的有点hackish代码,直到OnRowUpdating事件触发,或者我完全走错路?

2 个答案:

答案 0 :(得分:1)

你是对的,它很长,但在包括一些代码,JIC。

你似乎无法用普通的DataBinding做到这一点。我不太热衷于在会话中存储它,但我确实理解你不想要回发。

您可能想要做的是设置一个Ajax调用,以便您可以将新记录(或记录更改)粘贴到DataContext中。提交表单后,您可以在DataContext上调用SubmitChanges。

答案 1 :(得分:1)

对我来说,Josh试图从教师成员网格中管理你的多对多关系并不是正确的方法。事实上,我无法真实地想象出这将如何在网格内工作,我不是对你迷路而感到惊讶:)

最好使用“详细信息”页面,其中上下文=对一个Faculty成员,并为部门成员维护提供“双重列表”界面。这将包含2个列表。

右侧列表显示了教员已经成为其成员的所有部门(DivisionMembership行,其中FacultymemberId =上下文ID),左侧列表将显示所有剩余的部门。然后你可以提供'&gt;&gt;'和'&lt;&lt;&lt;列表之间的按钮,用于添加/删除部门中的Faculty成员(插入/删除DivisionMemberships行)

迈克尔