วิธีการเข้าร่วมใน linq ถึง sql กับไวยากรณ์วิธี?


193

ฉันเคยเห็นตัวอย่างมากมายใน LINQ ไปยังตัวอย่าง SQL เกี่ยวกับวิธีการเข้าร่วมในแบบสอบถามไวยากรณ์ แต่ฉันสงสัยว่าจะทำอย่างไรกับไวยากรณ์ของวิธีการ? เช่นฉันจะทำสิ่งต่อไปนี้ได้อย่างไร

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

ด้วย.Join()หรือ ทุกคนสามารถแสดงหรือให้ตัวอย่างง่ายๆได้อีกหรือไม่

คำตอบ:


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

จะเทียบเท่ากับ:

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

อย่างที่คุณเห็นเมื่อมาถึงการรวมไวยากรณ์แบบสอบถามมักจะอ่านได้ง่ายกว่าแลมบ์ดาไวยากรณ์


129

selectจัสตินได้แสดงให้เห็นการขยายตัวในกรณีที่มีผู้ติดตามเข้าร่วมเพียงแค่ได้อย่างถูกต้อง หากคุณมีอย่างอื่นมันจะกลายเป็นเรื่องยุ่งยากมากขึ้นเนื่องจากตัวระบุโปร่งใส - กลไกที่คอมไพเลอร์ C # ใช้เพื่อเผยแพร่ขอบเขตของทั้งสองส่วนของการเข้าร่วม

ดังนั้นเพื่อเปลี่ยนตัวอย่างของจัสตินเล็กน้อย:

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 }

จะถูกแปลงเป็นบางสิ่งเช่นนี้:

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 });

zนี่คือตัวระบุโปร่งใส - แต่เพราะมันเป็นโปร่งใสคุณไม่สามารถดูได้ในแบบสอบถามเดิม :)


5

หากต้องการเพิ่มคำตอบอื่น ๆ ที่นี่หากคุณต้องการสร้างวัตถุใหม่ประเภทที่สามด้วยคำสั่งย่อย (เช่นที่ไม่ใช่วัตถุ Entity Framework ของคุณ) คุณสามารถทำได้:

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;

}    

ให้ความสนใจเป็นพิเศษกับวัตถุระดับกลางที่สร้างขึ้นในส่วน Where and Select

โปรดทราบว่าที่นี่เรายังมองหาวัตถุที่เข้าร่วมใด ๆ ที่มีคุณสมบัติ 1 ที่ตรงกับหนึ่งในวัตถุในรายการอินพุต

ฉันรู้ว่ามันซับซ้อนกว่าสิ่งที่ผู้ถามเดิมกำลังมองหา แต่หวังว่ามันจะช่วยใครซักคน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.