J'essaye ce que je pense être un scénario plutôt simple de liaison de données avec Linq To SQL.Liaison de données hiérarchique avec Linq to SQL
J'ai une table de FacultyMembers, dont le schéma ressemble à ceci:
- FacultyMemberID - int PK
- Nom - nvarchar
- UniversityID - int FK à la table Université
et ainsi de suite. Il existe plusieurs autres propriétés de chaîne.
Je génère des classes de données LTS. Je dépose un LinqDataSource et un GridView sur une page, j'accepte la mise à jour et la suppression pour les deux, et je suis sur ma voie joyeuse. Pas de code, et je suis capable de mettre à jour mes propriétés de chaîne. Un peu de manipulation avec un DropDownList sur l'UniversityID et je suis capable de mettre à jour cette relation one-to-many, aussi. Yay. Maintenant, disons que je jette dans une table de mappage plusieurs-à-plusieurs. Disons que DivisionMemberships, qui mappe les membres de la Faculté aux divisions. DivisionMembership utilise le schéma simple et évidente:
- FacultyMemberID - int PK, FK à table FacultyMembers
- DivisionID - int PK, FK à la table des divisions
Maintenant, quand je prends une ligne de mon GridView dans EditMode, je rencontre un problème parce que je ne sais pas comment mettre à jour la relation many-to-many. Je me suis baladé avec quelques alternatives, et maintenant j'essaye de faire fonctionner un ListView. Je fais quelque chose comme ceci:
<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>
et ainsi de suite. Une partie du bavardage ci-dessus est supprimée, mais ListView est assez verbeux tel quel, donc je ne veux pas surcharger la page.
choses à noter ici:
- Pour mon association Université, j'utilise une nouvelle LinqDataSource et requête pour les éléments où les UniversityID correspond, puis lier la nouvelle UniversityID (valeur DDL) au FacultyMember, alors que pour la DivisionMemberships, je lie directement à la propriété (comme décrit here)
- J'utilise DataBinder. Bind() pour UniversityID, alors que j'utilise DataBinder. Eval() pour DivisionMemberships.
Si je passe à Bind() pour DivisionMemberships, j'obtiens une exception NotSerializableException pour EntitySet. Si je reste avec Eval(), je dois écrire moi-même les méthodes OnDelete et OnInsert pour ListView, et je ne veux pas supprimer ou insérer les DivisionMemberships jusqu'à ce que toute la ligne FacultyMember quitte EditMode. Je créerais probablement un DataContext et le collerais dans la session pour cela, parce que je n'ai pas d'autre moyen de marquer les membres de Division pour les mises à jour.
Je pense que ce scénario serait assez facile à activer hors de la boîte, mais je suis perdu. Des conseils sur où aller à partir d'ici?Spécifiquement, devrais-je lutter avec Bind() et essayer de rendre sérielle EntitySet, dois-je mordre la balle et écrire le code quelque peu hackish décrit ci-dessus pour stocker un DataContext en session jusqu'à ce que l'événement OnRowUpdating se déclenche, ou vais-je complètement?
Ouf, ce fut une longue . Pardon! J'espère que vous êtes en mesure de donner un sens à cela. – JoshJordan