Làm thế nào để tham gia linq đến sql với cú pháp phương thức?


193

Tôi đã thấy rất nhiều ví dụ trong các ví dụ LINQ to SQL về cách thực hiện tham gia cú pháp truy vấn nhưng tôi tự hỏi làm thế nào để làm điều đó với cú pháp phương thức? Ví dụ: làm thế nào tôi có thể làm như sau

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

với một .Join()? Bất cứ ai có thể minh họa hoặc cung cấp một ví dụ đơn giản khác?

Câu trả lời:


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

Sẽ tương đương với:

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

Như bạn có thể thấy, khi nói đến tham gia, cú pháp truy vấn thường dễ đọc hơn nhiều so với cú pháp lambda.


128

Justin đã thể hiện chính xác sự mở rộng trong trường hợp tham gia được theo sau bởi a select. Nếu bạn đã có một cái gì đó khác, nó sẽ trở nên khó khăn hơn do các định danh minh bạch - cơ chế mà trình biên dịch C # sử dụng để truyền bá phạm vi của cả hai nửa của phép nối.

Vì vậy, để thay đổi ví dụ của Justin một chút:

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 }

sẽ được chuyển đổi thành một cái gì đó như thế này:

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

Đây zlà định danh trong suốt - nhưng vì nó trong suốt nên bạn không thể thấy nó trong truy vấn ban đầu :)


5

Để thêm vào các câu trả lời khác ở đây, nếu bạn muốn tạo một đối tượng mới thuộc loại khác thứ ba với mệnh đề where (ví dụ: không phải là đối tượng Entity Framework của bạn), bạn có thể làm điều này:

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;

}    

Đặc biệt chú ý đến đối tượng trung gian được tạo trong mệnh đề Where và Chọn.

Lưu ý rằng ở đây chúng tôi cũng tìm kiếm bất kỳ đối tượng đã tham gia nào có thuộc tính1 khớp với một trong những đối tượng trong danh sách đầu vào.

Tôi biết điều này phức tạp hơn một chút so với những gì người hỏi ban đầu đang tìm kiếm, nhưng hy vọng nó sẽ giúp được ai đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.