1

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?

+0

Ouf, ce fut une longue . Pardon! J'espère que vous êtes en mesure de donner un sens à cela. – JoshJordan

Répondre

1

Vous avez raison, c'est long, mais bravo sur l'ajout de code, JIC.

Il semble évident que vous ne serez pas en mesure de faire cela avec DataBinding ordinaire. Je ne suis pas trop désireux de stocker cette session, mais je comprends que vous ne voulez pas de publication. Ce que vous voulez faire est de configurer un appel Ajax afin que vous puissiez coller votre nouvel enregistrement (ou votre changement d'enregistrement) dans le DataContext. Lorsque le formulaire est soumis, vous pouvez appeler SubmitChanges sur le DataContext.

+0

+ 1 pour lire et me donner une perspective cohérente :) Vous mentionnez que vous n'êtes pas trop désireux d'utiliser la session pour cela, et honnêtement, je ne suis pas non plus. Je préférerais avoir une demande atomique - des idées sur la façon dont vous l'auriez traité? J'adore l'idée d'Ajax. – JoshJordan

+0

Eh bien, l'appel Ajax vous permettrait de faire un appel "mettre à jour cette appartenance" au DataContext, sans nécessiter une publication complète. L'Ajax peut potentiellement être manipulé avec l'un des contrôles/panneaux du gestionnaire de scripts Ajax. Je suis désolé de ne pas être plus qualifié pour répondre à votre question plus en détail. J'ai construit un prototype pour quelque chose il y a quelques mois, mais j'ai été frustré et je suis passé à ASP.NET MVC. Dans MVC, cela peut être géré soit par un appel AJAX ou un appel JSON, et il frappe directement une méthode spécifique sur une classe C#. –

1

Il me semble qu'essayer de gérer votre relation plusieurs-à-plusieurs à partir de la grille des membres de la Faculté n'est pas la bonne approche.En fait, je ne peux pas vraiment voir comment cela fonctionnerait dans une grille, je suis Pas étonnant que vous soyez perdu :)

Mieux vaut utiliser une page de «détail» où le contexte est = à un seul membre du corps professoral et fournir une interface «double liste» pour l'entretien des membres de la division. Cela consisterait en 2 listes.

La liste de droite montre toutes les divisions auxquelles le membre de faculté est déjà membre (Rangées DivisionMembership où FacultymemberId = l'ID de contexte), la liste de gauche afficherait toutes les divisions restantes. Vous pouvez ensuite fournir « >> » et les boutons « < < » entre les listes d'ajouter/retirer le membre du corps professoral des divisions (Insertion/suppression de lignes de DivisionMemberships)

Michael

+0

+1 pour la réponse, comme ci-dessus. Je suis d'accord - je voulais faire quelque chose de similaire. En fait, j'ai une telle page, mais j'ai aussi une exigence pour permettre la gestion directement à partir de cette grille. Mon intuition me dit qu'il devrait être facile de lier à une propriété de liste (DivisionMemberships) du parent BindingContainer, mais il semble que ce n'est pas supporté. Je veux aussi utiliser autant de code autogénéré (non-ad-hoc) que possible. – JoshJordan

+0

Mais qu'allez-vous lier? Il faudrait que ce soit une liste multi-sélection, n'est-ce pas? ou une liste de cases à cocher ?? –

+0

Une liste de cases à cocher n'est pas difficile à visualiser. Il devrait être possible de le lier. – Danra