2012-12-07 9 views
0

J'ai deux tables, A et B, qui sont complètement indépendantes mais toutes deux ont une colonne time, qui est de type DateTime.LINQ - comment obtenir n enregistrements de deux tables?

Quelle requête LINQ simple dois-je écrire pour obtenir les 10 enregistrements les plus récents (basés sur le champ time) des deux tables, dans une collection? Par exemple, cette requête peut renvoyer 7 enregistrements de A et 3 enregistrements d'enregistrements B-10 au total.

+0

Vous devez joindre la table B du tableau A. Jetez un oeil à cette page: http://www.dotnetperls.com/join. Il décrit comment les jointures peuvent être réalisées avec LINQ. – Carsten

+0

Y a-t-il d'autres colonnes dans les tables A et B qui sont communes comme la colonne "Time"? Parce que vous n'avez pas spécifié l'enregistrement de sortie pour la requête que vous voulez obtenir. Si les deux tables sont complètement différentes, vous pouvez créer un enregistrement de sortie anonyme. Si A et B ont les mêmes colonnes que vous pouvez faire Union. – pawciu

+0

Les deux tables * peuvent partager une colonne, en fonction de la conception de ma base de données. Pouvez-vous montrer un exemple pour ce que vous voulez dire? –

Répondre

2
var _result = tableA 
       .Select(x => x.time) 
       .Union(tableB.Select(y => y.time)) 
       .OrderByDescending(z => z.time) 
       .Take(10); 

SOURCE

+0

'z.time' n'est pas reconnu ...? En outre, cela semble retourner les colonnes 'time' seulement, ce qui fait que' _result' est un 'IQueryable '. Je ne veux pas juste le temps, je veux toutes les colonnes ... Le 'time' ne devrait être utilisé que pour déterminer quels 10 enregistrements sont choisis. –

+0

comment à ce sujet 'var _result = tableA \t \t \t .Union (tableB) \t \t \t .OrderByDescending (z => z.time) \t \t \t .Take (10);'? –

+0

Ne semble pas fonctionner car 'Union' attend seulement' tableA' comme argument. –

0

Je vais vous donner l'exemple X-Com. Laissez vos tables stocker les données pour l'expédition vers la base x-com. Permet à la table A de recruter un magasin et à la table B de stocker des éléments. Vous voulez afficher la liste des recrues et des éléments qui a été envoyé à la base de tri par date:

//soldiers 
    public class RowA 
    { 
     public long Id {get;set;} 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public DateTime Date { get; set; } 
    } 
    //items 
    public class RowB 
    { 
     public long Id {get;set;} 
     public string ItemName { get; set; } 
     public decimal Quantity { get; set; } 
     public DateTime Date { get; set; } 
    } 

    List<RowA> TableA; 
    List<RowB> TableB; 

    public Form1() 
    { 
     InitializeComponent(); 
     PrepareTestData(); 

     int uniqueId = 0; 
     var result = (from a in TableA 
         //Map soldiers to anonymous 
         select new 
         { 
          UniqueId = uniqueId++, 
          InnerId = a.Id, 
          Name = a.FirstName + " " + a.LastName, 
          Date = a.Date, 
         }) 
        .Union(from b in TableB 
          select new 
          { 
           UniqueId = uniqueId++, 
           InnerId = b.Id, 
           Name = b.ItemName, 
           Date = b.Date, 
          }).OrderByDescending(x => x.Date).ToList(); 
     dataGridView1.AutoGenerateColumns = true; 
     dataGridView1.DataSource = result; 

    } 

    void PrepareTestData() 
    { 
     TableA = new List<RowA>(); 
     for (int i = 0; i < 7; ++i) 
      TableA.Add(new RowA 
      { 
       Id = i + 1, 
       FirstName = "Name" + i, 
       LastName = "Surname" + i, 
       Date = DateTime.Now.AddDays(-i) 
      }); 
     TableB = new List<RowB>(); 
     for (int j = 0; j < 4; ++j) 
      TableB.Add(new RowB 
      { 
       Id = j + 1, 
       ItemName = "Laser pistol", 
       Quantity = 7, 
       Date = DateTime.Now.AddDays(-j) 
      }); 
    } 

Vous pouvez également créer la classe pour l'enregistrement de sortie:

public Form1() 
    { 
     InitializeComponent(); 
     PrepareTestData(); 

     int uniqueId = 0; 
     var result = (from a in TableA 
         //Map soldiers to ShipmentReportItem 
         select new ShipmentReportItem 
         { 
          UniqueId = uniqueId++, 
          InnerId = a.Id, 
          Name = a.FirstName + " " + a.LastName, 
          Date = a.Date, 
         }) 
        .Union(from b in TableB 
          select new ShipmentReportItem 
          { 
           UniqueId = uniqueId++, 
           InnerId = b.Id, 
           Name = b.ItemName, 
           Date = b.Date, 
          }).OrderByDescending(x => x.Date).ToList(); 
     dataGridView1.AutoGenerateColumns = true; 
     dataGridView1.DataSource = result; 
    } 

classe Un résultat serait utile pour Vue grille ASP.NET si vous avez besoin d'un enregistrement de vérification ou de modyfing. Ensuite, vous aurez un accès facile à l'élément de source de données lorsque vous avez défini le type ou bien vous devrez obtenir le type de dataitem, puis vérifier ses propriétés, etc. obtenir des valeurs de propriété spécifique.

Et si votre table B stocke également des personnes (ont les mêmes colonnes), vous n'avez pas besoin de correspondance car la structure de la ligne sera la même.

Questions connexes