2009-04-04 6 views
0

Je viens juste d'apprendre à utiliser Entity Framework pour écrire un programme de surveillance de réseau C# très simple - c'est un exercice d'apprentissage pour essayer de «rentrer chez moi» ce que je suis. J'ai seulement lu à propos de ce jour. Je suis également nouveau à C# et LINQ (juste pour compliquer les choses plus loin.)Une requête Entity Framework débutant pour remplir un WinForms ListView

Je crois que j'ai le modèle de données convenablement normalisé mais je peux me tromper. Visual Studio génère un modèle conceptuel qui semble OK. J'ai pluralisé les associations et EntitySets si nécessaire, mais j'ai du mal à effectuer ce que je pense être une requête/projection assez basique sur les données.

La base de données contient 3 tables:

[Server] - A server defined by the user that should be pinged. 
ServerID - primary key 
HostAddress - IP or hostname 

[Result] - A result containing data about the last server test 
ResultID - primary key 
ServerID - foreign key on [Server].[ServerID] 
StateID  - an integer used to lookup one of 3 possible Server states 
TimeStamp - Time stamp of last ping 

[State]  - A lookup table containing an integer -> string mapping. 
StateID  - a unique key 
StateLabel - human-readable string like "unreachable" or "OK" or "timeout" 

je manuellement peuplé la base de données en utilisant quelques entrées simples - juste assez pour me donner quelque chose à travailler.

Pour commencer, je voudrais présenter toutes les données de résultat dans un ListView sur un formulaire WinForm. Le ListView contient les colonnes statiques suivantes:

État | Adresse du serveur | Dernière vérification

En théorie, les données de l'ListView doit être générée par la projection dans chacune des 3 tables (?):.

  • La colonne « Etat » doit afficher le [Etat] lisible par l'homme [ StateLabel] liée de [Résultat]. [StateID]
  • La colonne "Adresse du serveur" doit afficher [serveur]. [HostAddress] liée de [Résultat]. [ServerID]
  • La "Dernière vérification" colonne doit afficher [ Résultat]. [TimeStamp]

Puisque je n'ai pas besoin de la matérialisation de l'objet et/ou des fonctions de suivi des changements d'ObjectServices, ai-je raison de penser qu'il serait plus efficace/correct d'utiliser Entity SQL/EntityClient et DbDataReader? Si oui, à quoi ressemblerait une requête Entity SQL appropriée?

Pour ce que ça vaut, j'essayé d'utiliser LINQ aux entités et types anonymes dans une méthode, mais a été contrariée par un manque de compréhension sur un type de retour approprié:

var results = from r in _context.Result 
select new 
{ 
    State = (from s in _context.State 
     where s.StateId == r.StateId 
     select s.StateLabel), 
    r.ServerReference.Value.HostAddress, 
    r.TimeStamp 
}; 

return results.ToList(); // <- No can do. 

Merci pour votre aide!

Steve

Répondre

1

Eh bien vous ne serez pas en mesure de retourner une liste de types anonymes à moins que vous les jeter à object et ont la signature de définir le type de retour comme List<object> (ou interface appropriée). L'autre problème est que la sous-requête pour State renverra effectivement un IQueryable au lieu d'une seule entrée (vous pouvez utiliser la méthode d'extension First avec EF pour obtenir le premier élément correspondant.) Bien que si vous avez la relation de clé étrangère, le modèle doit être configuré une propriété de navigation pour l'état et vous devriez pouvoir utiliser la propriété attachée au lieu d'une sous-requête. Donc, si vous voulez avoir ceci comme un appel de méthode qui renvoie une liste d'objets, vous devrez créer un type qui représente la transformation ou la descente vers l'objet. Sinon, vous pouvez le faire au niveau du formulaire (tout dépend de vos besoins) lorsque vous essayez de lier la liste.Et comme je l'ai dit, l'autre alternative est de créer une classe pour la transformation ou de lier directement la liste à la requête.

public class SimpleStuff 
{ 
    public string State { get; set; } 
    public string HostAddress { get; set; } 
    public DateTime TimeStamp { get; set; } 
} 

Ensuite, il suffit d'ajouter la classe à la select new ala select new SimpleStuff et changer la signature de la méthode pour refléter la classe et de supprimer la distribution dans le retour.

+0

Merci Quintin, l'exemple de code a beaucoup aidé. – TheLearningCurve