2013-05-09 28 views
9

Dưới đây là một số mã đó (rõ ràng) không biên dịch:Cú pháp để thực thi khối mã bên trong truy vấn LINQ?

var q = from x in myAnonymousTypeCollection 
     select new { 
      x.ID, 
      CalcField = { 
         switch(x.SomeField) { 
          case 1: 
          return Math.Sqrt(x.Field1); 
          case 2: 
          return Math.Pow(x.Field2, 2); 
          default: 
          return x.Field3; 
         } 
         } 
     }; 

Bạn nhận được các hình ảnh; Tôi đang cố gắng tính CalcField theo cách hoàn toàn khác, tùy thuộc vào giá trị của SomeField là gì. Tôi không thể sử dụng Func<> (hoặc có thể?), Vì loại đầu vào là ẩn danh. Vậy cú pháp đúng để làm việc này là gì?

+0

Đây có phải là LINQ to Objects không? – cadrell0

+1

Sử dụng hàm lambda hoặc một hàm ẩn danh. –

+0

@ofstream - Tôi biết tôi có thể làm điều đó bằng cách sử dụng lambda, nhưng vì lý do dễ đọc trong mã thực tế của tôi, tôi muốn sử dụng cú pháp truy vấn. –

Trả lời

9

Trước hết, tôi thường thích cú pháp chuỗi phương thức hơn cú pháp truy vấn cho LINQ. Với điều đó bạn có thể làm điều này một cách dễ dàng.

var q = myAnonymousTypeCollection 
    .Select(x => 
      { 
       object calcField; 

       switch(x.SomeField) 
       { 
         case 1: 
         calcField = Math.Sqrt(x.Field1); 
         case 2: 
         calcField = Math.Pow(x.Field2, 2); 
         default: 
         calcField = x.Field3; 

       return new 
         { 
          x.ID, 
          CalcField = calcField 
         }; 
      }); 

Không sử dụng chuỗi phương pháp, bạn cần phương pháp hoặc Func. Hãy giả sử một Func

//replace these with actual types if you can. 
Func<dynamic, dynamic> calculateField = 
    x => 
    { 
     switch(x.SomeField) { 
      case 1: 
       return Math.Sqrt(x.Field1); 
      case 2: 
       return Math.Pow(x.Field2, 2); 
      default: 
       return x.Field3; 
    } 

var q = from x in myAnonymousTypeCollection 
     select new { x.Id, CalcField = calculateField(x) }; 

Lưu ý: Tôi không viết điều này trong IDE, vì vậy, xin vui lòng bào chữa bất kỳ lỗi đơn giản nào.

Đây là MSDN cho dynamic. Tuy nhiên, tôi đã tìm thấy rằng một khi bạn cần phải bắt đầu đi qua các loại vô danh xung quanh, tốt nhất là tạo một lớp thực tế.

+0

+1 Ooh, lén lút, sử dụng 'động'! Mặc dù vậy, tôi thích các kiểu mạnh hơn và cho đến bây giờ tôi sẽ có tùy chọn đầu tiên (cú pháp lambda). Đang chờ một cú pháp truy vấn hợp lệ (nếu có) trước khi cho bạn trả lời tín dụng. :-) –

7

Bạn có thể bao hàm chức năng ẩn danh của mình với tư cách là đại biểu (tự thực thi) Func<>. Điều này giả định bạn biết kiểu trả về.

var q = from x in myAnonymousTypeCollection 
    select new { 
     ID = x.ID, 
     CalcField = new Func<double>(() => { 
        switch(x.SomeField) { 
         case 1: 
         return Math.Sqrt(x.Field1); 
         case 2: 
         return Math.Pow(x.Field2, 2); 
         default: 
         return x.Field3; 
        } 
        })() 
    }; 
+0

+1: thật tuyệt! khái niệm này tương tự với javascript: thực thi hàm ẩn danh: '(function() {...})();' –

+0

Lưu ý rằng trong một tình huống như thế này có lẽ tốt nhất từ ​​quan điểm dễ đọc/bảo trì để trích xuất điều này một hàm được đặt tên mà bạn chỉ cần gọi trong truy vấn LINQ, mặc dù điều này sẽ hoạt động. – Servy

+0

+1 rất đẹp. Điều gì xảy ra nếu kiểu trả về cũng ẩn danh? :-) –

0

Bạn có thể khá dễ dàng di chuyển logic switch ra vào chức năng khác như vậy:

private static T GetReturnValue<T>(myClass x) 
{ 
    switch (x) 
    { 
     case 1: 
      return Math.Sqrt(x.Field1); 
      break; 
     case 2: 
      return Math.Pow(x.Field2, 
          2); 
      break; 
     default: 
      return x.Field3; 
      break; 
    } 
} 

Và sau đó bạn chỉ cần phải vượt qua đối tượng của bạn để chức năng đó để lấy lại giá trị mà bạn muốn:

var q = from x in myAnonymousTypeCollection 
        select new 
         { 
          ID = x.ID, 
          CalcField = GetReturnValue(x) 
         }; 
+0

Chắc chắn, điều đó sẽ dễ dàng nếu tôi có một kiểu xác định, giống như bạn làm ('myClass'). Nhưng tôi đang sử dụng một loại ẩn danh ... –

Các vấn đề liên quan