Chuyển đổi kết quả truy vấn Linq thành từ điển


346

Tôi muốn thêm một số hàng vào cơ sở dữ liệu bằng Linq vào SQL, nhưng tôi muốn thực hiện "kiểm tra tùy chỉnh" trước khi thêm các hàng để biết liệu tôi có phải thêm, thay thế hoặc bỏ qua các hàng không liên quan hay không. Tôi muốn giữ các đề tài giữa máy khách và máy chủ DB càng thấp càng tốt và giảm thiểu số lượng truy vấn.

Để làm điều này, tôi muốn lấy ít thông tin theo yêu cầu để xác thực và chỉ một lần khi bắt đầu quá trình.

Tôi đã nghĩ làm một cái gì đó như thế này, nhưng rõ ràng, nó không hoạt động. Bất cứ ai có một ý tưởng?

Dictionary<int, DateTime> existingItems = 
    (from ObjType ot in TableObj
        select (new KeyValuePair<int, DateTime>(ot.Key, ot.TimeStamp))
    )

Những gì tôi muốn có ở cuối sẽ là một Từ điển, mà không phải tải xuống toàn bộ các đối tượng ObjectType từ TableObject.

Tôi cũng đã xem xét mã sau đây, nhưng tôi đã cố gắng tìm một cách thích hợp:

List<int> keys = (from ObjType ot in TableObj orderby ot.Key select ot.Key).ToList<int>();
List<DateTime> values = (from ObjType ot in TableObj orderby ot.Key select ot.Value).ToList<int>();
Dictionary<int, DateTime> existingItems = new Dictionary<int, DateTime>(keys.Count);
for (int i = 0; i < keys.Count; i++)
{
    existingItems.Add(keys[i], values[i]);
}

Câu trả lời:


632

Hãy thử sử dụng các ToDictionaryphương pháp như sau:

var dict = TableObj.ToDictionary( t => t.Key, t => t.TimeStamp );

2
@pawan, đó là một trình giữ chỗ cho từng thành phần trong bảng liệt kê và đảm nhận loại đối tượng trong bảng liệt kê.
tvanfosson

1
@pawan - điều đó không đúng. Tôi mong đợi var servers = list.Select( s => new { s.ProjectName, Url = "tcp://" + s.BuildMachineName + ":" + s.PortNumber + "/CruiseManager.rem" } ).ToDictionary( s => s.ProjectName, s.Url ); Điều này tạo ra một từ điển được khóa bởi tên dự án của các cặp tên / url dự án.
tvanfosson

3
Tại sao .Select( t => new { t.Key, t.TimeStamp } )biểu thức cần thiết?
Ben Collins

9
@BenCollins: Tôi nghĩ rằng trung gian .Selectkhiến SQL được tạo chỉ chọn Key và TimeStamp, thay vì chọn mỗi cột.
Joey Adams

1
Bạn có thể bỏ qua trung gian này Selectnếu bạn đang thực hiện Linq to Object (thay vì Linq sang SQL)
Pac0

119

Nhìn vào ví dụ của bạn, tôi nghĩ đây là những gì bạn muốn:

var dict = TableObj.ToDictionary(t => t.Key, t=> t.TimeStamp);

Wow ... Nó có thể đơn giản như vậy ... Vì tôi khá mới để lập trình, tôi sẽ thử điều đó và làm một chút hồ sơ để đảm bảo rằng dưới mui xe, tôi không nhận được cú đánh của toàn bộ đối tượng. Tôi sẽ giữ cho bạn được đăng.
Tipx

1
Tôi chỉ thực hiện kiểm tra của tôi. Đáng buồn thay, trong khi nhận được TableObj, nó tìm nạp tất cả các đối tượng từ db để cuối cùng tôi nhận được các lượt truy cập. Tôi cũng đã kiểm tra các truy vấn theo cách thứ hai tôi đã đăng (và muốn tránh) và họ chỉ nhận được các mục cần thiết. Chắc chắn nó thực hiện 2 truy vấn để bản thân máy chủ phải tìm kiếm hai lần các bảng, nhưng ánh xạ đối tượng đủ đơn giản.
Tipx

7
Bạn có thể làm được: TableObj.Select (t => new {t.Key, t.TimeStamp}). ToDixi (t => t.Key, t => t.TimeStamp); LinqToSql sẽ có thể nhận thấy rằng bạn chỉ muốn hai thứ (từ lựa chọn) và trả lại chúng. Tôi không chắc nó đủ thông minh để đi sâu vào chi tiết cụ thể của ToDipedia ().
Talljoe

1
ĐẸP! Đây là truy vấn kết quả: CHỌN [t0]. [Khóa], [t0]. [TimeStamp] TỪ [TableObj] AS [t0]. Tôi không muốn nhận tín dụng cho việc này vì vậy hãy tiếp tục và đăng nó với tư cách là một anwser! :-P
Tipx

8

Hãy thử như sau

Dictionary<int, DateTime> existingItems = 
    (from ObjType ot in TableObj).ToDictionary(x => x.Key);

Hoặc loại đầy đủ phiên bản suy luận

var existingItems = TableObj.ToDictionary(x => x.Key);

Cảm ơn các anwser JaredPar. Tôi đã dạy về một cái gì đó tương tự, nhưng tôi nghĩ rằng điều này sẽ trả về toàn bộ các đối tượng thuộc loại ObjType và Iwant để tránh phải tải xuống toàn bộ các đối tượng.
Tipx

@Tipx, bạn có thể cung cấp một số thông tin về những gì bạn muốn lọc không? Có thể thêm một mệnh đề bộ lọc, nhưng tôi không thể biết từ câu hỏi của bạn điều gì quan trọng
JaredPar

Tất cả những gì tôi cần phải biết nếu "hàng mới" cần được thêm vào, được bỏ qua hoặc thay thế một hàng khác là dấu thời gian của đối tượng. Các đối tượng trong DB có nhiều trường tôi không cần xác thực và tôi không muốn đạt được hiệu suất đạt được toàn bộ các đối tượng. Để đơn giản, tôi đã lấy một bảng trong BD của mình với 20 cột, 100 000 hàng và tôi muốn trích xuất một Từ điển bằng cách sử dụng các giá trị của 2 cột đầu tiên.
Tipx

Tôi vừa kiểm tra các truy vấn máy chủ được tạo bởi mã đó và như bạn có thể biết, nó nhận được toàn bộ các đối tượng.
Tipx

0

Sử dụng không gian tên

using System.Collections.Specialized;

Ví dụ về DataContextlớp học

LinqToSqlDataContext dc = new LinqToSqlDataContext();

Sử dụng

OrderedDictionary dict = dc.TableName.ToDictionary(d => d.key, d => d.value);

Để truy xuất các giá trị sử dụng không gian tên

   using System.Collections;

ICollection keyCollections = dict.Keys;
ICOllection valueCollections = dict.Values;

String[] myKeys = new String[dict.Count];
String[] myValues = new String[dict.Count];

keyCollections.CopyTo(myKeys,0);
valueCollections.CopyTo(myValues,0);

for(int i=0; i<dict.Count; i++)
{
Console.WriteLine("Key: " + myKeys[i] + "Value: " + myValues[i]);
}
Console.ReadKey();

Đối với các phím Multilple ?
Kiquenet
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.