2013-09-01 3 views
1

Je suis un démarreur avec programmation dans LINQ et je voudrais savoir comment je peux imprimer toutes les données d'une table (dans SQL Server) en utilisant LINQ à partir d'une application console. Ce que j'ai fait jusqu'à maintenant est de créer une table appelée Response qui a plusieurs champs (j'ai conçu la table dans SQL Server Management Studio) et ai écrit une console C# class pour imprimer toutes les valeurs. Voici mon code pour cela:Imprimer un tableau avec LINQ

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace LinqConsoleApplication 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      using (DatabaseDBDataContext responses = new DatabaseDBDataContext()) 
      { 
       IEnumerable<Response> responses = from response in responses.Responses select response; 

       foreach (Response response in responses) 
       { 

        Console.WriteLine(response); 
       } 
       Console.ReadKey(); 
      } 

     } 
    } 
} 

Cependant, quand je lance ce cmd, je reçois cela comme ma sortie:

LinqConsoleApplication.Response

LinqConsoleApplication.Response

De googler certaines solutions, j'ai trouvé que Console.WriteLine(response) devrait retourner TOUT (select *) à partir d'une table, mais cela ne semble pas être le cas. Des suggestions s'il vous plaît? Y a-t-il une erreur dans la façon dont j'ai encadré la requête? Aurai-je besoin d'utiliser une méthode StringBuilder pour ajouter chaque champ au writeLine()?

+1

Console.WriteLine (response.Name); peut être? – rene

+0

'Console.WriteLine (response)' est en train d'imprimer 'response.ToString()', qui est le nom de type de 'Response'. Je pense que vous devez imprimer une * propriété * de votre objet 'response'. –

+0

@rene, cela retournerait seulement la valeur du nom, mais je veux que toutes les valeurs des champs soient imprimées. Aucune suggestion? –

Répondre

2

Vous pouvez le faire en utilisant la réflexion. Assurez-vous que vous utilisez System.Reflection.

static void Main(string[] args) 
{ 
    using (AcumenProjectsDBDataContext acumenResponse = new AcumenProjectsDBDataContext()) 
    { 
    IEnumerable<Response> responseData = from response in acumenResponse.Responses select response; 
    //added code 
    foreach (Response response in responseData) 
    { 
     foreach (PropertyInfo prop in response.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) 
     { 
      object value = prop.GetValue(response, new object[] { }); 
      Console.WriteLine("{0} = {1}", prop.Name, value); 
     } 
     } 
     Console.ReadKey(); 
    } 

} 
+0

Je le ferais dans le remplacement ToString du type, sinon c'est à usage unique. –

+0

Cette réponse obtient la sortie désirée, mais comme le dit retailcoder, il pourrait être un peu exagéré. Merci beaucoup à tous pour les conseils. –

0

Nous ne pouvons pas vous donner une réponse définitive jusqu'à ce que nous sachions de quoi est fait Response et ce que vous voulez imprimer, mais si vous voulez garder votre appel Console.WriteLine exactement comme il est, vous devez le remplacer la méthode ToString() dans votre classe Response, pour renvoyer la chaîne que vous souhaitez voir imprimée.

public override string ToString() 
{ 
    return string.Format("Property1: {0}\nProperty2: {1}\nProperty3: {2}", 
         this.Property1, this.Property2, this.Property3); 
} 

C'est parce que Console.WriteLine appellera implicitement la méthode ToString sur un type qui n'est pas un string, et l'implémentation par défaut de ToString renvoie simplement le nom du type.


Cela devrait fonctionner:

public class Response 
{ 
    ... 

    public override string ToString() 
    { 
     return string.Format("ResponseID: {0}\nStatusID: {1}\nTitle: {2}\nProjectID: {3}\nSourceID: {4}\nSourceTitle: {5}\n...", 
      ResponseID, StatusID, Title, ProjectID, SourceID, SourceTitle); 
     // no need to call .ToString() on integer properties here, it's called implicitly anyway 
    } 
} 

sortie pour Console.WriteLine(Response);

ResponseID: 1 
StatusID: 123 
Title: This is the title 
ProjectID: 1 
SourceID: 456 
SourceTitle: This is the source title 

Dans votre ToString override vous pouvez spécifier exactement comment vous voulez que chaque propriété apparaisse, par exemple {0:C2} serait imprimez 1 sous la forme $1.00. Vous pouvez également utiliser \t (onglet) pour aligner la sortie.

+0

Eh bien, vous ne le feriez qu'une fois, ToString indique au système comment votre classe devrait se rendre en tant que chaîne. L'alternative est d'utiliser la réflexion qui imho est un peu exagéré. –

+0

Est-ce que dataGridView.DataSource = dc.GetTable fonctionnerait dans ce cas? Si oui, comment puis-je l'utiliser pour imprimer le résultat? –

+0

Vous utiliseriez exactement le même code que vous avez posté dans votre question! :) –

1

Regardez le type de la variable "réponse" dans votre boucle foreach. C'est LinqConsoleApplication.Response. Lorsqu'un objet est transmis à la méthode Console.WriteLine(object), la méthode ToString() est appelée pour cet objet. Lorsque vous appelez la méthode ToString() d'un objet sans l'ignorer explicitement et en implémentant une fonctionnalité personnalisée, le résultat par défaut est que vous obtenez le type d'objet complet en tant que chaîne, par exemple. "LinqConsoleApplication.Response".

Ce que vous devez faire est de tout itérer dans la boucle foreach pour créer une chaîne personnalisée qui est créé par une concaténation des propriétés de l'objet dans lequel vous êtes intéressé par

Par exemple:.

foreach (Response response in responseData) 
      { 
       string responseString = response.SomeProperty1.ToString() + " " + response.SomeProperty2.ToString(); 
       Console.WriteLine(responseString); 
      } 
+0

Vous voudrez peut-être modifier votre réponse pour réellement * utiliser * la chaîne que vous construisez. Sinon la sortie reste inchangée ... –

+0

C'est ce que j'ai fait pour l'instant, mais que puis-je faire quand une table contient plus de 15 champs? Aurais-je explicitement convertir chaque champ àString() et les imprimer? Ce serait beaucoup d'écriture de code, non? Existe-t-il un concept DataTable dans LINQ qui peut renvoyer toutes les données (pour tous les champs) d'une table? –

+0

De cette façon, il s'agit d'une chaîne à usage unique, vous devez tout retaper (ou copier/coller) chaque fois que vous avez besoin de rendre votre type en tant que chaîne. –