2009-02-09 21 views
17

Điều gì (nếu có) là sự khác biệt giữa kết quả của hai phiên bản sau của truy vấn VB Linq này?Cú pháp "Mới ... Với" làm gì trong VB Linq?

'giả sử chúng ta có một XElement có chứa thông tin chi tiết của nhân viên được xác định ở một nơi khác

Dim ee = From e In someXML.<Employee> _ 
Select New With {.Surname = e.<Surname>, .Forename = e.<Forename>} 

Dim ee = From e In someXML.<Employee> _ 
Select Surname = .Surname = e.<Surname>, .Forename = e.<Forename> 

tức là những gì điểm của Tân ... Với cú pháp?

Tôi nghi ngờ rằng điều này có một câu trả lời đơn giản, nhưng tôi không thể tìm thấy nó - bất kỳ liên kết đến hướng dẫn phù hợp hoặc tài liệu của Microsoft sẽ được đánh giá cao.

Trả lời

14

Sự khác biệt là số 1 tạo rõ ràng loại ẩn danh. Thứ hai là biểu thức truy vấn và có thể sử dụng loại hiện có thay vì tạo loại ẩn danh. Từ tài liệu được liên kết bởi Cameron MacFarland:

Biểu thức truy vấn không phải lúc nào cũng yêu cầu tạo các loại ẩn danh. Khi có thể, họ sử dụng loại hiện có để giữ dữ liệu cột. Điều này xảy ra khi truy vấn trả về toàn bộ bản ghi từ nguồn dữ liệu hoặc chỉ một trường từ mỗi bản ghi.

+0

Nó không chỉ có nghĩa là khi bạn đang chọn một cột _single_ không có loại vô danh? Vì vậy, nó không áp dụng cho ví dụ trên, trong đó 2 cột được sử dụng. –

+0

Có, có thể không có sự khác biệt trong ví dụ đó. Nhưng trong trường hợp _general_, đó là chênh lệch _potential_. Ngoài ra, nó có thể sử dụng một loại hiện có nếu bạn mang lại toàn bộ hồ sơ, vì vậy nó không chỉ cho các cột đơn lẻ. –

+0

Cả hai loại mã sử dụng một loại ẩn danh, luôn luôn. – JaredPar

1

Chúng được gọi là Anonymous Types.

Lý do chính cho việc sử dụng chúng là giữ dữ liệu từ truy vấn trong một đối tượng duy nhất, do đó các trình vòng lặp có thể tiếp tục lặp qua danh sách đối tượng.

Chúng có xu hướng hoạt động như các loại tạm thời để lưu trữ ở giữa truy vấn LINQ lớn hoặc nhiều phần.

+0

Có - Tôi biết chúng là gì, nhưng nếu có thì khác biệt giữa hai dạng cú pháp này là gì? Liên kết bạn cung cấp đưa ra ví dụ về cả hai biểu mẫu nhưng không cho biết chúng có tương đương hay không. –

+0

Chắc chắn điều đó có nghĩa là: Tôi đã chỉ ra chính xác vị trí của liên kết đó cho bạn. –

+0

ok - kết hợp liên kết Cameron của bạn với lời giải thích của Joel có ý nghĩa bây giờ. Cảm ơn tất cả các bạn rất nhiều. –

2

Sự hiểu biết của tôi là không có sự khác biệt.

New With là nhằm mục đích out-of-truy vấn sử dụng như

Dim X = New With { .Surname = "A", .Forename = "B" } 

Cụ thể cho các truy vấn LINQ, bạn có thể bỏ New With, nhưng nó vẫn còn hữu ích cho các tình huống khác. Tôi không chắc chắn, tuy nhiên, vì tôi không biết VB 9 :)

+0

Tùy thuộc vào truy vấn, Thuộc tính đã thêm tùy chỉnh, bạn đã thêm vào các lớp một phần hoặc các trường khác sẽ chỉ đọc nếu không được trả lại trong Loại ẩn danh rõ ràng, sử dụng cú pháp Chọn mới với {}. – Nathan

0

Một sự khác biệt là các loại ẩn danh không thể tuần tự hóa được.

2

Không có sự khác biệt về chức năng giữa hai đoạn mã bạn đã liệt kê. Dưới mui xe cả hai đoạn mã sẽ sử dụng một loại vô danh để trả lại dữ liệu từ truy vấn.

Đoạn mã đầu tiên chỉ làm cho việc sử dụng loại ẩn danh rõ ràng. Lý do cú pháp này được cho phép là có thể trả về bất kỳ loại nào từ một mệnh đề Select. Nhưng loại phải được sử dụng một cách rõ ràng.

Dim x = From it in SomeCollection Select New Student With { .Name = it.Name } 

Joel không chính xác trong tuyên bố của mình rằng truy vấn thứ hai có thể sử dụng loại hiện có. Nếu không có một kiểu rõ ràng, một mệnh đề select sử dụng một tên thuộc tính rõ ràng sẽ luôn trả về một kiểu ẩn danh.

1

Không có sự khác biệt. Trình biên dịch sẽ suy ra kiểu ẩn danh.

Bạn có nhiều khả năng muốn trả về Giá trị của các phần tử như trong e.<Surname>.Value, trả về một Chuỗi thay vì một XElement.

dụ thứ 2 của bạn có thể được đơn giản hóa như

Dim ee = From e In someXML.<Employee> _ 
     Select e.<Surname>.Value, e.<Forename>.Value 

vì trình biên dịch cũng sẽ suy ra tên của các thành viên của kiểu nặc danh.

Tuy nhiên, nếu bạn có lớp sau

Class Employee 

    Private _surname As String 
    Public Property Surname() As String 
     Get 
      Return _surname 
     End Get 
     Set(ByVal value As String) 
      _surname = value 
     End Set 
    End Property 

    Private _forename As String 
    Public Property Forename() As String 
     Get 
      Return _forename 
     End Get 
     Set(ByVal value As String) 
      _forename = value 
     End Set 
    End Property 

End Class 

Sau đó, bạn có thể thay đổi các truy vấn 1 để tạo ra một IQueryable(Of Employee) thay vì kiểu nặc danh bằng cách sử dụng mới ... Với như vậy:

Dim ee = From e In someXML.<Employee> _ 
     Select New Employee With {.Surname = e.<Surname>.Value, _ 
            .Forename = e.<Forename>.Value} 
Các vấn đề liên quan