Untuk mendapatkan nilai maksimal dari kolom yang berisi integer, saya dapat menggunakan perintah T-SQL berikut
SELECT MAX(expression )
FROM tables
WHERE predicates;
Apakah mungkin untuk mendapatkan hasil yang sama dengan Entity Framework.
Katakanlah saya memiliki model berikut
public class Person
{
public int PersonID { get; set; }
public int Name { get; set; }
public int Age { get; set; }
}
Bagaimana cara mengetahui usia orang tertua?
int maxAge = context.Persons.?
c#
sql
entity-framework
max
Richard77
sumber
sumber
Jika daftar kosong saya mendapatkan pengecualian. Solusi ini akan mempertimbangkan masalah ini:
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
sumber
await _context.Persons.MaxAsync(x => (int?)x.Age) ?? 0
Atau Anda dapat mencoba ini:
(From p In context.Persons Select p Order By age Descending).FirstOrDefault
sumber
Mungkin membantu, jika Anda ingin menambahkan beberapa filter:
context.Persons .Where(c => c.state == myState) .Select(c => c.age) .DefaultIfEmpty(0) .Max();
sumber
maxAge = Persons.Max(c => c.age)
atau sesuatu seperti itu.
sumber
Kolom Anda tidak dapat diisi
int maxAge = context.Persons.Select(p => p.Age).Max() ?? 0;
Kolom Anda tidak dapat dinihilkan
int maxAge = context.Persons.Select(p => p.Age).Cast<int?>().Max() ?? 0;
Dalam kedua kasus tersebut, Anda dapat menggunakan kode kedua. Jika Anda menggunakan
DefaultIfEmpty
, Anda akan melakukan kueri yang lebih besar di server Anda. Untuk orang yang tertarik, berikut adalah EF6 yang setara:Kueri tanpa
DefaultIfEmpty
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT MAX([Extent1].[Age]) AS [A1] FROM [dbo].[Persons] AS [Extent1] ) AS [GroupBy1]
Kueri dengan
DefaultIfEmpty
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT MAX([Join1].[A1]) AS [A1] FROM ( SELECT CASE WHEN ([Project1].[C1] IS NULL) THEN 0 ELSE [Project1].[Age] END AS [A1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1] LEFT OUTER JOIN (SELECT [Extent1].[Age] AS [Age], cast(1 as tinyint) AS [C1] FROM [dbo].[Persons] AS [Extent1]) AS [Project1] ON 1 = 1 ) AS [Join1] ) AS [GroupBy1]
sumber
int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
Seperti yang dikatakan banyak orang - versi ini
int maxAge = context.Persons.Max(p => p.Age);
melempar pengecualian saat tabel kosong.
Menggunakan
int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
atau
int maxAge = context.Persons.Select(x => x.Age).DefaultIfEmpty(0).Max()
sumber
Di VB.Net itu akan
Dim maxAge As Integer = context.Persons.Max(Function(p) p.Age)
sumber
int maxAge = context.Persons.Max(p => p.Age);
Versi ini, jika daftarnya kosong :
null
- untuk kelebihan beban nullableSequence contains no element
pengecualian - untuk kelebihan beban yang tidak dapat dinolkan-
int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();
Versi ini menangani kasus daftar kosong, tetapi menghasilkan kueri yang lebih kompleks, dan untuk beberapa alasan tidak berfungsi dengan EF Core.
-
int maxAge = context.Persons.Max(p => (int?)p.Age) ?? 0;
Versi ini elegan dan berkinerja baik (kueri sederhana dan sekali jalan pulang pergi ke database), bekerja dengan EF Core. Ini menangani pengecualian yang disebutkan di atas dengan mentransmisikan tipe non-nullable ke nullable dan kemudian menerapkan nilai default menggunakan
??
operator.sumber
Jawaban yang dipilih melontarkan pengecualian, dan jawaban dari Carlos Toledo menerapkan pemfilteran setelah mengambil semua nilai dari database.
Yang berikut menjalankan satu perjalanan bolak-balik dan membaca satu nilai, menggunakan indeks apa pun yang memungkinkan, tanpa pengecualian.
int maxAge = _dbContext.Persons .OrderByDescending(p => p.Age) .Select(p => p.Age) .FirstOrDefault();
sumber