2010-03-13 35 views
10

Hôm qua I posted this question liên quan đến việc sử dụng lambdas bên trong phương thức Join() để kiểm tra xem có 2 điều kiện tồn tại trên 2 thực thể hay không. Tôi đã nhận được câu trả lời cho câu hỏi, câu hỏi này đã hoạt động hoàn hảo. Tôi nghĩ sau khi đọc bài viết MSDN trên phương thức Enumerable.Join(), tôi sẽ hiểu chính xác những gì đã xảy ra, nhưng tôi thì không. Ai đó có thể giúp tôi hiểu những gì đang xảy ra trong các mã dưới đây (các Tham gia() phương pháp đặc biệt)? Cảm ơn trước.Trợ giúp Hiểu Enumerable.Join Phương pháp

if (db.TableA.Where(a => a.UserID == currentUser) 
     .Join(db.TableB.Where(b => b.MyField == someValue), 
      o => o.someFieldID, 
      i => i.someFieldID, 
      (o,i) => o) 
     .Any()) 
{ 
    //... 
} 

Chỉnh sửa: Cụ thể, tôi tò mò về 3 thông số cuối cùng và những gì đang diễn ra. Làm thế nào để họ dẫn đến việc yêu cầu chữ ký của Func (TOuter, TKey), Func (thợ thiếc, TKey) vv

Trả lời

3

Eric và Nick đều cung cấp câu trả lời hay.

Bạn cũng có thể viết biểu thức truy vấn LINQ bằng cú pháp truy vấn (so vớicú pháp phương pháp, mà bạn đang sử dụng trong ví dụ của bạn):

var query = from a in db.TableA 
      join b in db.TableB on a.someFieldID equals b.someFieldID 
      where a.UserID == currentUser && b.MyField == someValue 
      select a; 

     if (query.Any()) { 
      ... 
     } 

Cập nhật:

Bạn dường như bị mắc kẹt trên các biểu thức lambda. Đó là một hàm mà bạn truyền xung quanh như một biến. Một biểu thức lambda tương đương với một đại biểu ẩn danh (hoặc phương thức nặc danh, với tôi tổng quát hơn).

Đây là truy vấn của bạn với các biểu thức lambda như các đại biểu (thay thế EntityType với các loại hình tổ chức của bạn trở về từ TableA, tất nhiên):

if (db.TableA.Where(delegate(EntityType a) { return a.UserID == currentUser; }) 
    .Join(db.TableB.Where(delegate(EntityType b) { return b.MyField == someValue; }), 
     delegate(EntityType o) { return o.somefieldId); }, 
     delegate(EntityType i) { return i.someFieldId); }, 
     delegate(EntityType o, EntityType i) { return o; }) 
    .Any()) 

{// ... }

LƯU Ý: Một biểu thức lambda có các khía cạnh quan trọng khiến cho nó không chỉ đơn thuần là tương đương với các phương thức nặc danh. Tôi khuyên bạn nên xem qua các câu hỏi SO khác và đọc trực tuyến về các biểu thức lambda nói riêng. Chúng cho phép những ý tưởng rất mạnh mẽ được thể hiện một cách đơn giản và thanh lịch hơn nhiều. Đó là một chủ đề sâu sắc, nhưng những điều cơ bản rất dễ hiểu. Đó là một hàm mà bạn có thể truyền xung quanh như một biến, hoặc như một tham số cho các hàm khác.

+0

Vâng, tôi thực sự đã viết nó theo cách này trước đây, sau đó sau khi nhận ra rằng nó có thể được thực hiện bằng cách sử dụng phương thức Join sử dụng lambdas, tôi nghĩ rằng tôi sẽ thử thách bản thân mình. Tôi vẫn tin rằng cách này rõ ràng hơn, và có lẽ sẽ thực hiện giải pháp theo cách này, nhưng tôi muốn hiểu đầy đủ kỹ thuật khác trước. –

+1

Trong ví dụ được cập nhật của bạn, không nên ủy quyền thứ hai (EntityType o) được ủy quyền (EntityType i)? –

+0

Vâng, cảm ơn Metro Smurf (Tôi không thể tin rằng hai từ đó xuất hiện từ cái khác đến lol). –

2

Truy vấn này đang nói tham gia TableA-TableB nơi TableA.someFieldID == TableB.someFieldID và chọn kết quả từ TableA và nhìn thấy nếu có bất kỳ kết quả ở tất cả các

Xét về SQL nghĩ về nó như thế này, ngay cả khi nó không phải là LINQ-to-SQL ... nếu bạn đã quen thuộc với SQL có lẽ điều này làm cho ý nghĩa hơn:

Select Count(*) 
From TableA a 
    Join TableB b 
     On a.someFieldID = b.someFieldID 

Sau đó, kiểm tra nếu Count(*) là> 0

15

Cú pháp nối là

FirstTable.Join(SecondTable, FirstTableKeyExtractor, SecondTableKeyExtractor, Selector) 

Vì vậy, bạn có hai bảng. Bạn có một số khóa chung cho cả hai bảng. Bạn cung cấp hai trình giải mã khóa để biết cách lấy khóa ra khỏi mỗi hàng trong bảng.

Logic tham gia xác định các cặp hàng, một từ mỗi bảng, có cùng một khóa.

Mỗi hàng trong số đó sau đó được chạy qua bộ chọn để hiển thị kết quả.

Điều đó có trả lời câu hỏi của bạn không?

+0

Hầu như. Tôi hiểu các tham số đầu tiên là một thực thể (của một bảng phù hợp với những điều kiện), nhưng tôi tò mò làm thế nào 3 tham số khác hoạt động. Chính xác những gì đang xảy ra tại thời điểm này: o => o.SomeFieldID, i => i.SomeFieldID, (o, i) => o –

+0

@lush - Tham số thứ hai cho biết trường nào trên bảng gốc bạn ' kết hợp lại trên ('TableA.someFieldID'), tham số thứ ba cho biết trường nào trên bảng đã nối mà bạn khớp với trường (' TableB.someFieldID'). Tham số cuối cùng nói từ bộ bảng mới được kết hợp này, những gì bạn đang chọn ... trong trường hợp này là mọi thứ từ 'TableA'. Trong mã của bạn, bạn có thể thay thế 'o' bằng' a' và 'i' bằng' b', điều đó có thể làm cho nó rõ ràng hơn rất nhiều. –

+0

Nhưng mã "o => o.SomeFieldID" dịch thành "TableA.SomeFieldID" như thế nào? Điều gì đang xảy ra dưới mui xe? –

4

Giải thích về Tham gia.

b = loại đối tượng của bảng đầu tiên o = loại đối tượng của bảng đầu tiên loại i = đối tượng của bảng thứ hai

  1. db.TableB.Where(b => b.MyField == someValue) Đây là loại nguyên tố của bảng thứ hai
  2. o => o.someFieldID Chìa khóa của bảng đầu tiên
  3. i => i.someFieldID Chìa khóa của bảng thứ hai (sẽ khớp với khóa trong bảng đầu tiên)
  4. (o,i) => o Đối tượng trả về, trong trường hợp này là kiểu đối tượng của bảng đầu tiên.
Các vấn đề liên quan