简体   繁体   中英

LINQ - how to get n records from two tables?

I have two tables, A and B, that are completely independent but both have a time column, which is of type DateTime .

What simple LINQ query do I need to write to get the 10 most recent (based on the time field) records from both tables, in one collection? For example, this query might return 7 records of A and 3 records of B - 10 records in total.

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

SOURCE

I'll give you X-Com example. Let your tables store data for shipment to x-com base. Let table A store recruits, and table B store items. You want to display list of recruits and items that has been shipped to base sorting by 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)
            });
    }

You also can create class for output record:

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;
    }

One result class would be usefull for ASP.NET gridview if you need some checking or modyfing record. Then you will have easy acces to datasource item when you have defined type or else you would have to get dataitem type, then check its properties etc. get values from specific property.

And if your table B also stores people(have same columns) you dont need mapping because row struct will be the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM