2008-10-16 7 views
10

Mon code pour la connexion SQL LINQ est:instruction switch dans LINQ

var query1 = from u in dc.Usage_Computers 
      where u.DomainUser == s3 
      select u; // selects all feilds from table 

GridView1.DataSource = query1; 
GridView1.DataBind(); 

J'ai un champ appelé "Opération" dans le tableau "DomainUser" qui a des valeurs comme "1, 2, 3". Lorsque je remplissais ces valeurs dans la grille de données, je voulais les convertir en valeurs significatives comme si la valeur de Operation est 1 puis afficher dans dataagrid comme "logon", si 2 puis "logoff" etc ...

Comment puis-je assigner des valeurs pour eux après avoir récupéré de la base de données?

+0

double possible de [déclaration LINQ cas] (http://stackoverflow.com/questions/936028/linq-case-statement) –

Répondre

12

Cette technique ne semble pas particulièrement applicable à votre problème, mais elle l'est quand même.

Vous pouvez créer une instruction SQL dans LinqToSql en utilisant le C# ? : opérateur.

var query1 = 
    from u in dc.Usage_Computers 
    where u.DomainUser == s3 
    select new {usage = u, 
    operation = 
     u.DomainUser.Operation == 1 ? "login" : 
     u.DomainUser.Operation == 2 ? "logoff" : 
     "something else" 
    }; 
+1

Pourquoi les gens veulent que la base de données transforme les entiers en chaînes d'étiquettes pour eux, je ne le saurai jamais. On dirait un travail pour le serveur web. –

+0

Merci David! Votre méthode a fonctionné pour moi! –

+0

tandis que la solution répond à la question, je pense que c'est une mauvaise pratique de saupoudrer la logique de conversion comme ça. Une telle logique de conversion devrait être centralisée dans une classe réutilisable. –

0

J'ai fait quelque chose de similaire en utilisant TemplateFields. Utilisation d'un ASP: Etiquette liée à la propriété et ajout d'un gestionnaire d'événement OnPreRender pour le contrôle. Dans le gestionnaire d'événements pour le contrôle que je traduis le texte en fonction de sa valeur et définir la nouvelle valeur:

protected void label_OnPreRender(object sender, EventArgs e) 
{ 
    Label l = (Label)sender; 
    switch (l.Text) { 
     case "1": 
     l.Text = "Logon"; 
     break; 
     ... 
     default: 
     break; 
    } 
} 

Si le formulaire est en mode édition, vous devrez gérer différemment. Vous devrez probablement ajouter des gestionnaires pour l'insertion et la mise à jour au contrôle View que vous utilisez pour traduire les données fournies par la page dans sa représentation de base de données.

2

Utilisez un champ de modèle dans votre gridview:

<asp:GridView ID="gvDomain" runat="server" OnRowDataBound="gvDomain_RowDataBound"> 
    <Columns> 
     <asp:TemplateField> 
      <HeaderTemplate> 
       Operation 
      </HeaderTemplate> 
      <ItemTemplate> 
       <asp:Label id="lblLogon" runat="server" /> 
      </ItemTemplate> 
     </asp:TemplateField> 
    </Columns> 
</asp:GridView> 

Utilisez ensuite les gridviews événement RowDataBound pour découvrir l'étiquette et affecter son texte:

Protected Sub gvDomain_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvStates.RowDataBound 
    Dim lblLogon As Label = DirectCast(e.Row.FindControl("lblLogon"), Label) 
    Dim drv As DataRowView = DirectCast(e.Row.DataItem, DataRowView) 

    If lblLogon IsNot Nothing Then 
     Select Case drv("Operation").ToString() 
      Case "1" 
       lblLogon.Text = "Logon" 
       Break 
      Case "2" 
       lblLogon.Text = "Logoff" 
       Break 
      //etc... 
     End Select 
    End If 
End Sub 
1
static Func<int?, string> MapSqlIntToArbitraryLabel = (i => 
{ 
    // for performance, abstract this reference 
    // dictionary out to a static property 
    Dictionary<int, string> labels = new Dictionary<int, string>(); 
    labels.Add(1, "logon"); 
    labels.Add(2, "logoff"); 
    labels.Add(...); 

    if (i == null) throw new ArgumentNullException(); 
    if (i < 1 || i > labels.Count) throw new ArgumentOutOfRangeException(); 

    return labels.Where(x => x.Key == i.Value) 
       .Select(x.Value) 
       .Single(); 
} 

que le retour déclaration peut également être exprimé comme:

return (from kvp in labels 
     where kvp.Key == i.Value 
     select kvp.Value).Single(); 

Ensuite, vous pouvez utiliser appeler cette fonction de votre requête LINQ comme ceci:

var query1 = from u in dc.Usage_Computers 
      where u.DomainUser == s3 
      select { 
       Operation = MapSqlIntToArbitraryLabel(u.Operation) 
       // add other properties to this anonymous type as needed 
      }; 

J'ai essayé toutes les méthodes suggéré de duper Linq2Sql dans l'exécution de mon code et cette méthode est la seule que j'ai trouvé qui permet moi d'exécuter du code dans le cadre d'une projection d'exécution différée.

+0

alors que je suis d'accord en général avec l'approche (+1), pense qu'il est peu trop. Un dictionnaire simple peut suffire (et fournir de meilleures performances). Aussi devrait initialiser une fois seulement. Une autre chose est la considération pour faire de la méthode de traduction une méthode d'extension à l'objet. –

+0

Les méthodes d'extension sur l'objet ont été mon premier essai, mais j'ai trouvé cette approche généralise bien - à partir de MapSqlIntToArbitraryLabel() vous pouvez appeler une méthode qui n'est pas reconnue par Linq2Sql et qui semble fonctionner sans étouffer à sql "problème. –

Questions connexes