Entity Framework kullanarak bir sütunun maksimum değeri nasıl elde edilir?


92

Tamsayı içeren bir sütunun maksimum değerini elde etmek için aşağıdaki T-SQL komutunu kullanabilirim

SELECT MAX(expression )
FROM tables
WHERE predicates;

Entity Framework ile aynı sonucu elde etmek mümkün mü?

Diyelim ki şu modelim var

public class Person
{
  public int PersonID { get; set; }
  public int Name { get; set; }
  public int Age { get; set; }
}

En yaşlı kişinin yaşını nasıl öğrenirim?

int maxAge = context.Persons.?

Yanıtlar:


152

Bunu dene int maxAge = context.Persons.Max(p => p.Age);

Ve using System.Linq;dosyanızın en üstünde olduğundan emin olun


2
Bununla biraz uğraştım çünkü "using System.Linq;" Benim gibi yeni başlayanlar için cevabınıza bu bilgiyi eklemeyi düşünmelisiniz :)
RagnaRock

2
Sorun @RagnaRock
krolik

3
Ama ya herhangi bir kaydınız yoksa ve EF hataları alıyorsa. Benim toplamam var model = db.BillOfLading.Select (x => x.No) .LastOrDefault (); eğer (model! = null) {var val = db.BillOfLading.Max (x => x.No);
HerGiz

Bu verimli mi? Veya varlık çerçevesinin Max işlevini kullanan bir saklı yordamı yürütmesi daha mı iyi olur? Varlık çerçevesi için yeni ve gerçekten merak ediyorum
TemporaryFix

@Programmatic kesinlikle daha verimli olacak bir sebep yok. Sql Server sürümü hariç <= 7.
mxmissile

49

Liste boşsa bir istisna alırım. Bu çözüm, bu sorunu dikkate alacaktır:

int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();

7
Kabul edilen cevap bu olmalıdır. Sunucuya yalnızca bir gidiş dönüş ve istisna yok.
9Rune5

4
Ancak tüm sütun değerlerini veritabanından alır ve uygulama tarafında Max uygular.
SuperDuck

1
Bu 3 alt sorgu yapar. Farklı bir cevap önerdim.
jsgoupil

3
sadece bir yan not - bu EF çekirdeği ile çalışmaz. Kullandım:await _context.Persons.MaxAsync(x => (int?)x.Age) ?? 0
egmfrs

11

Ya da şunu deneyebilirsiniz:

(From p In context.Persons Select p Order By age Descending).FirstOrDefault

7

Bir filtre eklemek isterseniz yardımcı olabilir:

context.Persons
.Where(c => c.state == myState)
.Select(c => c.age)
.DefaultIfEmpty(0)
.Max();

4
maxAge = Persons.Max(c => c.age)

veya bu çizgiler boyunca bir şey.


4

Sütununuz boş değer atanabilir

int maxAge = context.Persons.Select(p => p.Age).Max() ?? 0;

Sütununuz boş değer atanamaz

int maxAge = context.Persons.Select(p => p.Age).Cast<int?>().Max() ?? 0;

Her iki durumda da ikinci kodu kullanabilirsiniz. Eğer kullanırsanız DefaultIfEmpty, sunucunuzda daha büyük bir sorgu yapacağız. İlgilenenler için işte EF6 eşdeğeri:

Olmadan sorgu DefaultIfEmpty

SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        MAX([Extent1].[Age]) AS [A1]
        FROM [dbo].[Persons] AS [Extent1]
    )  AS [GroupBy1]

İle sorgu 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]

1
Peki yaint maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;
egmfrs

3

Birçoğunun dediği gibi - bu versiyon

int maxAge = context.Persons.Max(p => p.Age);

tablo boş olduğunda bir istisna atar.

Kullanım

int maxAge = context.Persons.Max(x => (int?)x.Age) ?? 0;

veya

int maxAge = context.Persons.Select(x => x.Age).DefaultIfEmpty(0).Max()

İkinci cevabınız bana iyi geliyor, birisi oluşturulan SQL'e bakarsa, 2. cevap iyidir.
Deepak Sharma

2

In VB.Net olurdu

Dim maxAge As Integer = context.Persons.Max(Function(p) p.Age)

2
int maxAge = context.Persons.Max(p => p.Age);

Liste boşsa bu sürüm :

  • İade null- null yapılabilir aşırı yüklemeler için
  • Özel Sequence contains no elementdurum atar - null yapılamayan aşırı yüklemeler için

-

int maxAge = context.Persons.Select(p => p.Age).DefaultIfEmpty(0).Max();

Bu sürüm boş liste durumunu işler, ancak daha karmaşık sorgu oluşturur ve bazı nedenlerden dolayı EF Core ile çalışmaz.

-

int maxAge = context.Persons.Max(p => (int?)p.Age) ?? 0;

Bu sürüm zarif ve performanslıdır (basit sorgu ve veritabanına tek gidiş-dönüş), EF Core ile çalışır. Null yapılamayan türü null yapılabilir olarak çevirerek ve ardından ??operatörü kullanarak varsayılan değeri uygulayarak yukarıda belirtilen istisnayı işler .


1

Seçilen cevap istisnaları atar ve Carlos Toledo'nun cevabı veri tabanından tüm değerleri aldıktan sonra filtreleme uygular.

Aşağıdakiler tek bir gidiş-dönüş çalıştırır ve istisnasız herhangi bir olası indeksi kullanarak tek bir değeri okur.

int maxAge = _dbContext.Persons
  .OrderByDescending(p => p.Age)
  .Select(p => p.Age)
  .FirstOrDefault();
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.