Pertanyaan LINQ Menggunakan Max () untuk memilih satu baris


Saya menggunakan LINQ pada IQueryable yang dikembalikan dari NHibernate dan saya perlu memilih baris dengan nilai maksimum (s) dalam beberapa bidang.

Saya telah menyederhanakan sedikit yang saya tempelkan. Saya harus memilih satu baris dari meja saya dengan nilai maksimum dalam satu bidang.

var table = new Table { new Row(id: 1, status: 10), new Row(id: 2, status: 20) }

from u in table
group u by 1 into g
where u.Status == g.Max(u => u.Status)
select u

Ini tidak benar, tetapi saya tidak bisa mencari bentuk yang tepat.

BTW, apa yang sebenarnya ingin saya capai adalah sekitar ini:

var clientAddress = this.repository.GetAll()
    .GroupBy(a => a)
    .SelectMany(
            g =>
            g.Where(
                a =>
                a.Reference == clientReference && 
                a.Status == ClientStatus.Live && 
                a.AddressReference == g.Max(x => x.AddressReference) && 
                a.StartDate == g.Max(x => x.StartDate)))
    .SingleOrDefault();

Saya mulai dengan lambda di atas tetapi saya telah menggunakan LINQPad untuk mencoba dan menyusun sintaks untuk memilih Max ().

MEMPERBARUI

Menghapus GroupBy adalah kuncinya.

var all = this.repository.GetAll();

var address = all
            .Where(
                a =>
                a.Reference == clientReference && 
                a.Status == ClientStatus.Live && 
                a.StartDate == all.Max(x => x.StartDate) &&
                a.AddressReference == all.Max(x => x.AddressReference))
            .SingleOrDefault();

75
2018-02-02 15:22


asal


Jawaban:


Saya tidak mengerti mengapa Anda mengelompokkan di sini.

Coba ini:

var maxValue = table.Max(x => x.Status)
var result = table.First(x => x.Status == maxValue);

Pendekatan alternatif yang akan berulang table hanya sekali saja ini:

var result = table.OrderByDescending(x => x.Status).First();

Ini sangat membantu jika table adalah IEnumerable<T> yang tidak ada dalam memori atau yang dihitung dengan cepat.


180
2018-02-02 15:30



Anda dapat mengelompokkan berdasarkan status dan memilih satu baris dari grup terbesar:

table.GroupBy(r => r.Status).OrderByDescending(g => g.Key).First().First();

Pertama First() mendapat grup pertama (kumpulan baris dengan status terbesar); kedua First() mendapat baris pertama di grup itu.
Jika statusnya selalu unqiue, Anda dapat mengganti yang kedua First() dengan Single().


12
2018-02-02 15:28



Anda juga bisa melakukan:

(from u in table
orderby u.Status descending
select u).Take(1);

10
2017-08-26 14:48



Mengatasi pertanyaan pertama, jika Anda perlu mengambil beberapa baris dikelompokkan berdasarkan kriteria tertentu dengan kolom lain dengan nilai maksimum Anda dapat melakukan sesuatu seperti ini:

var query =
    from u1 in table
    join u2 in (
        from u in table
        group u by u.GroupId into g
        select new { GroupId = g.Key, MaxStatus = g.Max(x => x.Status) }
    ) on new { u1.GroupId, u1.Status } equals new { u2.GroupId, Status = u2.MaxStatus}
    select u1;

5
2017-11-10 19:38



Secara sederhana dalam satu baris:

var result = table.First(x => x.Status == table.Max(y => y.Status));

Perhatikan bahwa ada dua tindakan. tindakan batin adalah untuk menemukan nilai maksimal, aksi luar adalah untuk mendapatkan objek yang diinginkan.


0
2017-11-13 12:25