.NET Core 3.0 Entity Framework'te bir grup katılımı nasıl gerçekleştirilir?


13

.NET Core 3.0'daki değişikliklerle

... NavigationExpandingExpressionVisitor 'başarısız oldu. Bu EF Çekirdeğindeki bir hatayı veya sınırlamayı gösterebilir. Daha ayrıntılı bilgi için https://go.microsoft.com/fwlink/?linkid=2101433 adresine bakın .) ---> System.InvalidOperationException: 'GroupJoin, LINQ ifadesinin işlenmesi, ...

Bu gerçekten basit bir sorgu, bu yüzden .NET CORE 3.0'da gerçekleştirmenin bir yolu olmalı:

 var queryResults1 = await patients
            .GroupJoin(
                _context.Studies,
                p => p.Id,
                s => s.Patient.Id,
                (p, studies) => new 
                {
                    p.DateOfBirth,
                    p.Id,
                    p.Name,
                    p.Sex,
                   Studies =studies.Select(s1=>s1)
                }
            )
            .AsNoTracking().ToListAsync();

Temelde Hastalar üzerine Çalışmalar katılmak ve verilen hasta için hiçbir çalışma varsa Çalışmalar boş bir liste veya null ayarlamak bir Linq sorgu (veya yukarıdaki gibi yöntem sözdizimi) arıyorum.

Herhangi bir fikir? Bu .NET Core 2.2'de çalışıyordu. Ayrıca yukarıdaki MSFT bağlantısı, anahtar kırılma değişikliğinin istemci tarafı değerlendirmesi ve oluşturulan sorgunun birleştirilmesi veya istemci tarafından filtrelenmesi gereken tüm tabloları okumasından kaçınmaktan bahsetmektedir. Ancak bu basit sorgu ile birleştirme kolayca sunucu tarafında yapılabilir olmalıdır.

Yanıtlar:


11

Bahsedildiği gibi burada , veritabanına tarafından desteklenmeyen bir sorgu çalışıyorsunuz. EF Core 2, kodunuzu çalıştırmak için istemci tarafı değerlendirmesini kullandı, ancak EF Core 3 reddediyor, çünkü veri seti arttıkça istemci tarafı rahatlığı, hata ayıklaması zor performans sorunlarının maliyetine neden oluyor.

DefaultIfEmptyHasta çalışmalarına katılmak için kullanın ve ardından manuel olarak gruplandırın ToLookup.

var query =
    from p in db.Patients
    join s in db.Studies on p.Id equals s.PatientId into studies
    from s in studies.DefaultIfEmpty()
    select new { Patient = p, Study = s };

var grouping = query.ToLookup(e => e.Patient); // Grouping done client side

Yukarıdaki örnek, tüm Hasta ve Çalışma varlıklarını alır, ancak bunun yerine sütunları kiraz olarak seçebilirsiniz. Hastadan ihtiyacınız olan veriler her Çalışma için tekrarlanamayacak kadar büyükse, birleştirilmiş sorguda yalnızca Hasta kimliğini seçin ve geri kalan Hasta verilerini ayrı bir katılmamış sorguda sorgulayın.


2
Cevap çalışıyor! Sorgu çevirmende hala yapılacak bazı işler var sanırım. Bunun gibi basit bir sorgu çevrilebilir olmalıdır. FK / dizinlerinin doğru olduğu varsayılarak veri kümesi artışı nedeniyle 2 tablodan oluşan basit bir grup birleşimi için performans sorunları olmamalıdır. Birçok kişi tis sorunu olacak şüpheli, 2 tablo grup katılmak oldukça standart ve sık kullanılan bir sorgu.
shelbypereira

@ she72 Kabul ediyorum. Sorun, LINQ ve SQL'in "grup" anahtar kelimesini kullanma biçimindeki farktan kaynaklanıyor gibi görünüyor. EF Core, LINQ'yu groupbysol birleşimlere çevirmelidir; burada yapılması beklenenden daha fazla satır geri çekilmez. Buna göre bir yorum gönderdim .
Edward Brey

Bir takip soru var, hala neden bu tür bir sorgu için gruplama istemci tarafında yapılması gerektiğini anlamaya çalışıyorum, yeni LINQ çerçevesinin bir sınırlama gibi görünüyor. Yukarıdaki durum için, istemci tarafında yürütmeyi beklenmedik şekillerde yavaşlatma riskini görmüyorum. Açıklayabilir misin?
shelbypereira

1
Ve daha sonraki bir takip olarak asıl endişe: hasta başına 1000 çalışmam varsa müşteri tarafını hangi grupların yeniden düzenlediği sorgunuzda, her hastayı DB'den 1000 kez yükleyeceğim? Bu çalışmanın DB'de yapılmasına ve gruplandırılmış sonuçların geri gönderilmesine zorlamanın bir alternatifi var mı?
shelbypereira

1
@ shev72 Veritabanını anlayan tek grup, örneğin, hasta başına çalışma sayısı olan hastaların bir sorgusu gibi kümeleri içerir. Veritabanı her zaman dikdörtgen bir veri kümesi döndürür. Hiyerarşik bir gruplama istemci tarafından oluşturulmalıdır. Buna müşteri tarafı değerlendirmesi veya ORM'nin bir parçası olarak bakabilirsiniz . Hiyerarşik bir gruplamada, ana varlık verileri tekrar sorgulanmasa da tekrarlanır.
Edward Brey

0

Tamamen aynı konu ve onunla büyük bir mücadele vardı. Net Core 3.0'ın yöntem sözdiziminde (henüz?) Join veya Groupjoin özelliğini desteklemediği ortaya çıkıyor. Eğlenceli kısmı olsa da, Sorgu sözdiziminde çalışır.

Bunu deneyin, biraz yöntem sözdizimi ile sorgu sözdizimi. Bu güzel bir güzel dış dış birleştirme ile doğru SQL sorgusu çevirir ve veritabanında işlenir. Modelleriniz yok, bu yüzden sentaksı kendiniz kontrol etmeniz gerekiyor ....

var queryResults1 = 
    (from p in _context.patients
    from s in _context.Studies.Where(st => st.PatientId == p.Id).DefaultIfEmpty()
    select new
    {
        p.DateOfBirth,
        p.Id,
        p.Name,
        p.Sex,
        Studies = studies.Select(s1 => s1)
    }).ToListAsync();

Bu arada, Join ve GroupJoin ile Method syntac DO, çekirdek olmayan Framework ve EF ile çalışır. Ve sunucu tarafı pocessed doğru sorguya çevirmek
hwmaat

1
çalışmalarda nedir. (s1 => s1)
Ankur Arora

Modeller soruya dahil edilmedi, bu yüzden çalışma modelini bilmiyorum. En iyi tahminim, bu modelde sanal bir koleksiyon.
hwmaat
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.