私は、LinqToSQLを使用したかなり単純なデータバインディングシナリオであると思うことを試みています。
FacultyMembersのテーブルがあり、そのスキーマは次のようになっています。
- FacultyMemberID-int PK
- 名前-nvarchar
- UniversityID-大学テーブルへのintFK
などなど。他にもさまざまな文字列プロパティがあります。
LTSDataClassesを生成します。LinqDataSourceとGridViewをページにドロップし、両方の更新と削除を有効にして、順調に進んでいます。コードはありません。文字列のプロパティを更新できます。UniversityIDのDropDownListを少し操作すると、その1対多の関係も更新できます。わーい。
ここで、多対多のマッピングテーブルを投入するとします。FacultyMembersをDivisionsにマップするDivisionMembershipsとしましょう。DivisionMembershipは、シンプルで明白なスキーマを使用します。
- FacultyMemberID-int PK、FKからFacultyMembersテーブル
- DivisionID-int PK、FKから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を使用して、UniversityIDが一致するアイテムをクエリし、新しいUniversityID(DDL値)をFacultyMemberにバインドしますが、DivisionMembershipsでは、プロパティに直接バインドします(ここで説明します) 。
- DataBinderを使用しています。私はDataBinderを使用していますが、UniversityIDのBind() 。DivisionMembershipsのEval() 。
DivisionMembershipsのBind()に切り替えると、EntitySetのNotSerializableExceptionが発生します。Eval()を使用する場合は、ListViewのOnDeleteメソッドとOnInsertメソッドを自分で作成する必要があり、FacultyMember行全体がEditModeを終了するまで、DivisionMembershipsを削除または挿入したくありません。更新のためにDivisionMembershipsをマークする別の方法がないため、おそらくDataContextを作成し、これをセッションに貼り付けます。
このシナリオは、箱から出してすぐに有効にするのは非常に簡単だと思いますが、私は迷っています。ここからどこへ行くべきかについて何かアドバイスはありますか?具体的には、Bind()と格闘して、EntitySetをシリアル化できるようにする必要がありますか、OnRowUpdatingイベントが発生するまで、セッションにDataContextを格納するための上記のややハックなコードを作成する必要がありますか、それとも完全に間違った方向に進んでいますか?