LINQ On Clause'de Birden Çok Koşulla Katıl


96

LINQ'da, ON yan tümcesinde birden çok koşulla bir sol dış birleşim kullanan bir sorgu uygulamaya çalışıyorum.

Aşağıdaki iki tablo Project (ProjectID, ProjectName) ve Task (TaskID, ProjectID, TaskName, Completed) örneğini kullanacağım. İlgili görevleriyle birlikte tüm projelerin tam listesini görmek istiyorum, ancak yalnızca tamamlanan görevler.

İçin filtre kullanamıyorum Completed == trueçünkü bu, tamamlanmış görevleri olmayan tüm projeleri filtreleyecektir. Bunun yerine Completed == true, birleşimin ON maddesine eklemek istiyorum, böylece projelerin tam listesi gösterilecek, ancak yalnızca tamamlanmış görevler gösterilecek. Tamamlanmış görev içermeyen projeler, Görev için boş değer içeren tek bir satır gösterecektir.

İşte sorgunun temeli.

from t1 in Projects
join t2 in Tasks
on new { t1.ProjectID} equals new { t2.ProjectID } into j1
from j2 in j1.DefaultIfEmpty()
select new { t1.ProjectName, t2.TaskName }

&& t2.Completed == trueOn maddesine nasıl eklerim ?

Bunun nasıl yapılacağına dair herhangi bir LINQ belgesi bulamıyorum.


Lambda sözdizimini kullanarak ilgili yanıt burada
StuartLC

Yanıtlar:


135

Sadece anonim mülke her iki tarafta da aynı isim vermeniz gerekiyor

on new { t1.ProjectID, SecondProperty = true } equals 
   new { t2.ProjectID, SecondProperty = t2.Completed } into j1

@Svick'in yorumlarına dayanarak, işte daha mantıklı olabilecek başka bir uygulama:

from t1 in Projects
from t2 in Tasks.Where(x => t1.ProjectID == x.ProjectID && x.Completed == true)
                .DefaultIfEmpty()
select new { t1.ProjectName, t2.TaskName }

2
Bunu yapmanın açık olmayan bir yolu gibi görünüyor. Ne yapması gerektiğini anlayacağımdan emin değilim.
svick

1
@svick - Anonim türleri kullanmak, birden çok kritere katılmanıza olanak tanır. Sadece özellik adlarının her iki türde de eşleştiğinden emin olmanız gerekir. Karışıklığın nereden geldiğinden emin değil misiniz?
Aducci

Buradaki karışıklık, and"tuhaf" bir nesnenin tek bir eşitliği değil, iki eşitliğin birleşmesiyle daha anlamlı hale geliyor . Ve benim fikrimi kanıtlamak için, kodunuz yanlış. Çalışması trueiçin sol tarafta ve t2.Completesağda olması gerekir.
svick

1
Teşekkürler Aducci. Bağlamı doğru bir şekilde elde etmek için sorguda tarafları değiştirmem gerekti, ama bu işe yaradı. Bu problem basitleştirildi ve benim gerçek dünyadaki problemimde sadece SecondProperty doğru ya da yanlış değil, SecondProperty bir tamsayı ve ben kullanıyorum AND SecondProperty IN (123, 456). Bu meydan okumaya devam edeceğim ve verebileceğiniz herhangi bir yardım çok takdir edilecektir.
Kuyenda

@svick - İyi yakaladım, t2'nin sırasını değiştirdim. Tamamlandı ve gerçek değer. Sizin için daha az tuhaf olabilecek başka bir çözüm ekledim.
Aducci

41

İşte şununla gidiyorsun:

from b in _dbContext.Burden 
join bl in _dbContext.BurdenLookups on
new { Organization_Type = b.Organization_Type_ID, Cost_Type = b.Cost_Type_ID } equals
new { Organization_Type = bl.Organization_Type_ID, Cost_Type = bl.Cost_Type_ID }

Bu daha anlaşılır görünüyor.
Bijay Yadav

1

Bunu böyle yapamazsın. Yan jointümce (ve Join()genişletme yöntemi) yalnızca equijoins'i destekler. Ayrıca kullanmasının equalsve kullanmamasının nedeni de budur ==. Ve böyle bir şey yapabilseniz bile işe yaramaz çünkü joinbu bir iç birleşimdir, dış birleşim değil.


Dış birleştirme talep edilmedi ve (diğer yanıtlara bakın), tabii ki yapabilirsiniz.
edc65

0

Bu 2 tablo için iyi çalışıyor. 3 tablom var ve on cümlesi 3 tablodan 2 koşulu birbirine bağlamam gerekiyor. Kodum:

p içinde _dbContext.Products, _dbContext.ProductVariants içindeki pv'yi birleştirin p.ProduktId eşittir pv.ProduktId jpr'yi yeni {VariantId = pv.Vid, ProductVID = p.ProduktId} eşittir new {Variant.Prices ProductId = jpr.Prices.ProduktID} 'yi lj'ye

Ancak bu noktada hata gösteriyor: p.ProduktId'deki _dbContext.ProductVariants içindeki pv'yi birleştirin pv.ProduktId

Hata: Join yan tümcesindeki ifadelerden birinin türü yanlış. 'GroupJoin' çağrısında tür çıkarımı başarısız oldu.


bu hata, ilk anonim nesnenin alan türlerinin ikinci olanlara karşılık gelmediği anlamına gelir. Türlerin VariantIdaynı ve bu türlerin aynı olduğunu kontrol edin ProductId. Örneğin, Guidvs olabilir Guid?- o zaman beğenmeniz gerekir VariantId = (Guid?) jpr.Prices.VariantID.
Evgeny Nozdrev
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.