Bagaimana cara bergabung di LINQ ke sql dengan sintaks metode?

193

Saya telah melihat banyak contoh dalam contoh LINQ to SQL tentang cara melakukan penggabungan dalam sintaks kueri tapi saya bertanya-tanya bagaimana melakukannya dengan sintaksis metode? Misalnya bagaimana saya bisa melakukan hal berikut

var result = from sc in enumerableOfSomeClass
             join soc in enumerableOfSomeOtherClass
             on sc.Property1 equals soc.Property2
             select new { SomeClass = sc, SomeOtherClass = soc }

dengan .Join()? Adakah yang bisa mengilustrasikan atau memberikan contoh sederhana lainnya?

chobo2
sumber

Jawaban:

283
var result = from sc in enumerableOfSomeClass
             join soc in enumerableOfSomeOtherClass
             on sc.Property1 equals soc.Property2
             select new { SomeClass = sc, SomeOtherClass = soc };

Akan sama dengan:

var result = enumerableOfSomeClass
    .Join(enumerableOfSomeOtherClass,
          sc => sc.Property1,
          soc => soc.Property2,
          (sc, soc) => new
                       {
                           SomeClass = sc,
                           SomeOtherClass = soc
                       });

Seperti yang Anda lihat, ketika harus bergabung, sintaks query biasanya lebih mudah dibaca daripada sintaks lambda.

Justin Niessner
sumber
129

Justin telah benar menunjukkan ekspansi dalam kasus di mana bergabung hanya diikuti oleh a select. Jika Anda memiliki sesuatu yang lain, itu menjadi lebih rumit karena pengidentifikasi transparan - mekanisme yang digunakan oleh kompiler C # untuk menyebarkan lingkup kedua bagian dari gabungan.

Jadi untuk sedikit mengubah contoh Justin:

var result = from sc in enumerableOfSomeClass
             join soc in enumerableOfSomeOtherClass
             on sc.Property1 equals soc.Property2
             where sc.X + sc.Y == 10
             select new { SomeClass = sc, SomeOtherClass = soc }

akan diubah menjadi sesuatu seperti ini:

var result = enumerableOfSomeClass
    .Join(enumerableOfSomeOtherClass,
          sc => sc.Property1,
          soc => soc.Property2,
          (sc, soc) => new { sc, soc })
    .Where(z => z.sc.X + z.sc.Y == 10)
    .Select(z => new { SomeClass = z.sc, SomeOtherClass = z.soc });

Di zsini adalah pengidentifikasi transparan - tetapi karena transparan, Anda tidak dapat melihatnya di permintaan asli :)

Jon Skeet
sumber
5

Untuk menambahkan jawaban lain di sini, jika Anda ingin membuat objek baru dari tipe ketiga berbeda dengan klausa where (mis. Yang bukan objek Entity Framework Anda), Anda bisa melakukan ini:

public IEnumerable<ThirdNonEntityClass> demoMethod(IEnumerable<int> property1Values)
{
    using(var entityFrameworkObjectContext = new EntityFrameworkObjectContext )
    {
        var result = entityFrameworkObjectContext.SomeClass
            .Join(entityFrameworkObjectContext.SomeOtherClass,
                sc => sc.property1,
                soc => soc.property2,
                (sc, soc) => new {sc, soc})
            .Where(s => propertyValues.Any(pvals => pvals == es.sc.property1)
            .Select(s => new ThirdNonEntityClass 
            {
                dataValue1 = s.sc.dataValueA,
                dataValue2 = s.soc.dataValueB
            })
            .ToList();
    }

    return result;

}    

Berikan perhatian khusus pada objek perantara yang dibuat di klausa Tempat dan Pilih.

Perhatikan bahwa di sini kami juga mencari objek yang bergabung yang memiliki properti1 yang cocok dengan salah satu yang ada di daftar input.

Saya tahu ini sedikit lebih kompleks daripada yang dicari si penanya, tapi semoga ini bisa membantu seseorang.

John Meyer
sumber