2010-01-27 26 views
5

Một trong những điều mà bạn đã đánh bại bạn là một nhà phát triển cơ sở là bạn không bao giờ, bao giờ làm một "SELECT *" trên một tập dữ liệu, vì nó không đáng tin cậy vì nhiều lý do.Linq no-noes - bắt tất cả sql giống như chọn?

Kể từ khi chuyển sang LINQ (trước hết là LINQ to SQL và sau đó là Khuôn khổ thực thể), tôi đã tự hỏi liệu tương đương LINQ có giống nhau không?

Ví dụ

var MyResult = from t in DataContext.MyEntity 
       where t.Country == 7 
       select t; 

Chúng ta có nên chọn vào một loại vô danh chỉ với các lĩnh vực, chúng tôi muốn đề cập một cách rõ ràng, hoặc là bắt tất cả các chọn bây giờ có thể chấp nhận cho LinqToSql et al vì công cụ bổ sung xung quanh các dữ liệu họ cung cấp?

Trân

Moo

+2

Những người nói bạn nên * không bao giờ *, * bao giờ * làm $ x chỉ là không có dấu hiệu như những người ** luôn luôn ** làm $ x. –

+0

Ồ, tôi hoàn toàn đồng ý, nhưng nó * là * một trong những quy tắc vàng ... – Moo

Trả lời

5

Nó không được tán thành, nó được xác định bởi trường hợp sử dụng của bạn. Nếu bạn muốn cập nhật kết quả và vẫn tồn tại thì bạn nên chọn t, tuy nhiên nếu bạn không muốn làm điều đó và chỉ truy vấn cho mục đích hiển thị, bạn có thể làm cho nó hiệu quả hơn bằng cách chọn thuộc tính bạn muốn:

var MyResult = from t in DataContext.MyEntity 
       where t.Country == 7 
       select new { t.Prop1, t.Prop2 }; 

Đây là vì một vài lý do. Dân số của một loại ẩn danh hơi nhanh hơn, nhưng quan trọng hơn là nó disables change tracking ... bởi vì bạn không thể tồn tại một loại ẩn danh, không cần phải theo dõi các thay đổi đối với nó.

Here's an excellent rundown of the common performance areas like this thật tuyệt vời khi bắt đầu. Nó bao gồm một lời giải thích sâu hơn về theo dõi thay đổi mà tôi vừa mô tả.

1

select t trong trường hợp này s chọn tất cả các lĩnh vực từ một loại biết đến. Nó được gõ mạnh mẽ và ít bị lỗi tương tự tìm thấy trong SQL.

Ví dụ trong SQL

INSERT INTO aTable 
SELECT * FROM AnotehrTable 

có thể thất bại nếu AnotherTable thay đổi, tuy nhiên trong LINQ/Net tình trạng này không xuất hiện.

Nếu bạn đang tham gia nhiều bảng, thì bạn không thể thực hiện select * trong LINQ, bạn sẽ phải tạo một loại ẩn danh với tất cả các loại chứa bên trong.

0

Tôi sẽ nói những gì bạn đang làm tương đương với tuyên bố SELECT *. Tốt hơn là chỉ trả lại các trường bạn yêu cầu, ví dụ:

var myResult = from t in DataContext.MyEntity 
       where t.Country == 7 
       select new T 
       { 
        Field1 = t.Field1, 
        Field2 = t.Field2 
       } 
+0

Điều gì sẽ xảy ra nếu bạn muốn mọi người trong MyEntity? Bạn có tạo một loại nặc danh giống với MyEntity không? – cjk

+1

Tôi đã có thể nghĩ (không được thử nghiệm) mà trở lại t như OP đã đề xuất, sẽ làm điều này cho bạn? – James

0

Bạn vẫn phải nêu rõ những gì bạn muốn chọn. Nếu bạn chọn tất cả, bạn vẫn đang kéo xuống nhiều dữ liệu hơn mức bạn cần và khi những thứ mới được thêm vào, bạn cũng sẽ không cần thiết phải kéo những dữ liệu đó. Nói chung, cách tốt nhất là kéo chỉ những gì bạn cần.

0

Sử dụng LINQ sẽ không làm giảm hiệu suất của việc nhận thêm trường.

Tuy nhiên, đó là không thể để tạo một SELECT * FROM ... bằng LINQ to SQL. Mã của bạn sẽ tạo một tuyên bố SELECT đặt tên rõ ràng tất cả các cột được xác định trong mô hình của bạn; nó sẽ bỏ qua bất kỳ thay đổi nào đối với cơ sở dữ liệu.

Tuy nhiên, hiệu suất vẫn là mối quan tâm, vì vậy bạn nên sử dụng loại ẩn danh nếu bạn chỉ sử dụng một số cột.

0

Có thể cần phải thực hiện điều đó như trong ví dụ, đặc biệt nếu những gì cần làm là thay đổi (các) hàng.

trong SQL select * khác với LINQ vì LINQ sẽ luôn trả về cùng một số cột (như được định nghĩa trong dbml).

1

Lý do tránh SELECT * là cơ sở dữ liệu bên dưới có thể thay đổi và do đó các lệnh cột có thể thay đổi có thể dẫn đến lỗi trong lớp truy cập dữ liệu của bạn.

Bạn không thực hiện SELECT * từ cơ sở dữ liệu của mình, bạn chỉ đang nói rằng bạn muốn "t" và mọi thứ đi kèm với nó. Không có gì sai với điều đó nếu đó thực sự là những gì bạn cần.

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