2009-07-01 24 views
44

thể trùng lặp:
LINQ to SQL: Return anonymous type?Làm thế nào để trở lại loại vô danh từ C# phương pháp có sử dụng LINQ to SQL

Tôi có một LINQ tiêu chuẩn để truy vấn SQL, mà trả về dữ liệu như một loại vô danh (chứa khoảng 6 cột dữ liệu của các kiểu dữ liệu khác nhau).

Tôi muốn làm cho đối tượng trả về này có sẵn cho các phần khác của chương trình, hoặc bằng cách trả lại cho người gọi phương thức hoặc bằng cách gán nó cho thuộc tính của đối tượng chứa phương thức.

Làm cách nào tôi có thể thực hiện việc này vì đây là loại ẩn danh ("var")?

EDIT - Đây là mã:

using (ormDataContext context = new ormDataContext(connStr)) 
    { 
     var electionInfo = from t1 in context.elections 
        join t2 in context.election_status 
        on t1.statusID equals t2.statusID 
        select new { t1, t2 }; 
    } 
+0

Các trường t1, t2 là gì? –

+0

Hãy để điều này như là một đường dẫn tới đường dẫn đến câu hỏi ban đầu. Để lại một bình luận nếu bạn nghĩ rằng hai câu hỏi nên được sáp nhập, và tôi sẽ kiểm tra lại sau. –

+0

Chỉ cần làm rõ, 'var' không phải là một kiểu ẩn danh. 'var' là một từ khóa viết tắt mà bạn có thể sử dụng cung cấp trình biên dịch có thể suy ra Kiểu. Trong trường hợp này, 'electionInfo' là kiểu ẩn danh. –

Trả lời

65

Hãy kiểu nặc danh vào một lớp học ...

public class Person 
{ 
    public Person() { 
    } 

    public String Name { get; set; } 
    public DateTime DOB { get; set; } 
} 


Person p = 
    from person in db.People 
    where person.Id = 1 
    select new Person { 
     Name = person.Name, 
     DOB = person.DateOfBirth 
    } 
+0

+1 tôi vừa mới đăng câu trả lời như thế này, đánh tôi với nó. :) –

+0

ghét nó khi điều đó xảy ra! :) –

+3

OK, vì vậy về cơ bản bạn đang nói không sử dụng lớp ẩn danh ... Tôi đồng ý rằng điều này có vẻ rõ ràng hơn rất nhiều. Tôi đoán tôi đang tự hỏi tại sao hầu hết các mẫu LINQ sử dụng var nếu họ rất khó khăn để làm việc với ... – alchemical

19

Bạn không thể gõ bất kỳ phương pháp trong C# là kiểu tường minh của một ẩn danh loại. Chúng không thể được "đặt tên" để nói và do đó không thể xuất hiện trong các chữ ký siêu dữ liệu.

Nếu bạn thực sự muốn trở lại một giá trị mà là một loại vô danh có 2 lựa chọn

  1. Có kiểu trả về của phương pháp này là System.Object. Sau đó, bạn có thể thực hiện các phép nhập dữ liệu ác để nhận giá trị đã nhập theo phương thức khác. Đây là rất mong manh và tôi không khuyên bạn nên dùng nó.
  2. Sử dụng phương pháp chung và mẹo loại suy luận để nhận loại trả về chính xác. Điều này đòi hỏi một định nghĩa chữ ký rất thú vị cho cách tiếp cận của bạn.

Các loại vô danh không thực sự có ý nghĩa để được truyền đi trong thời trang này. Tại thời điểm bạn cần phải vượt qua chúng xung quanh giữa các chức năng của bạn theo cách này, bạn tốt hơn tắt xác định rõ ràng một loại.

+1

Sử dụng kiểu dữ liệu động –

+0

'Tại thời điểm bạn cần truyền chúng giữa các hàm theo cách này, bạn nên xác định rõ ràng kiểu' [ Rõ ràng bạn không phải là một tay golf (JavaScript)] (https://s-media-cache-ak0.pinimg.com/736x/76/a3/9c/76a39cea29fe872eab52a6b4680f5c66.jpg). ; ^) – ruffin

5

Jon Skeet đã viết một blog về cách thực hiện điều này, có tên khá phù hợp với tiêu đề Horribly Grotty Hack. Cũng giống như tiêu đề gợi ý, bạn thực sự không nên tìm cách để trả lại một loại ẩn danh. Thay vào đó, bạn nên tạo một kiểu có thể được trả về vì đây là cách chính xác để triển khai tính năng này.

Vì vậy, tôi khuyên bạn nên tạo định nghĩa cụ thể về loại được trả lại và sau đó điền vào truy vấn đó để truy vấn nó được trả lại.

+0

... wistfully nhớ đối tượng recordset từ ASP cổ điển ... có vẻ như đây là một sự cân bằng giữa mã phức tạp và hiệu suất ...cho một chương trình nhỏ không có vấn đề lớn, nhưng trên một dự án lớn hơn với hàng trăm cuộc gọi db, tạo một đối tượng tùy chỉnh cho mỗi tập dữ liệu được truy xuất và phải thay đổi chúng nếu db thay đổi, nghe như đau và tăng độ phức tạp của mã. – alchemical

+0

Và sau đó bạn nên cân nhắc xem bạn có đang sử dụng công nghệ thích hợp cho công việc bạn đang làm hay không. Không sử dụng một spade khi những gì bạn cần là một cái búa. –

+0

vậy, làm thế nào tôi có thể có một đối tượng kiểu "recordset", tức là lưu trữ tất cả các kiểu trả về như các đối tượng được bao bọc trong một đối tượng .Net chuẩn mà tôi có thể di chuyển dễ dàng? – alchemical

6

Sử dụng var không biến nó thành loại ẩn danh. Sử dụng var chỉ có nghĩa là biến biến này là kiểu có sẵn ở phía bên tay phải của nhiệm vụ. Nó chỉ là bàn tay ngắn. Nếu điều ở bên tay phải là một lớp thực, biến sẽ thuộc loại đó.

Ví dụ:

var person = new Person { Name = "bob" }; 

Biến người là loại người, mặc dù nó được sử dụng từ khóa var.

Các loại ẩn danh được tạo bằng cách sử dụng {Name = ...} mới. Trong trường hợp này, đây là một lớp mới, ẩn danh.Điều duy nhất bạn có thể gán cho nó là một biến được định nghĩa bằng cách sử dụng var (hoặc đối tượng) vì không có tên hiện có để sử dụng.

Ví dụ:

var person = new { Name = "bob" }; 

Trong trường hợp này, người là một loại vô danh quy định tại thời gian chạy.

Nói chung, như @Chalkey cho biết, nếu bạn muốn chuyển kết quả trở lại phương thức khác, hãy sử dụng loại được đặt tên chứ không phải dạng ẩn danh.

Nếu bạn buộc phải sử dụng loại ẩn danh, bạn sẽ phải chuyển nó trở lại làm đối tượng thuộc loại Object, sau đó sử dụng phản chiếu để xem thuộc tính của nó.

+0

Tôi đã thử điều này với mã của tôi, nhưng biến mới được đặt tên ("Người" trong ví dụ của bạn), không chắc chắn trong intellisense như là một kiểu trả về có thể sử dụng cho phương pháp ... – alchemical

+0

Bạn cần phải đăng mã cho phương pháp để tôi cung cấp thêm cho bạn lời khuyên. – tvanfosson

+0

Thx, tôi vừa thêm mã vào câu hỏi. – alchemical

0

Nếu bạn phải vượt qua các kết quả trong một ứng dụng lớn, bạn có thể sử dụng Từ điển. Có bạn có một số chi phí khi đúc nhưng ít nhất bạn đang giảm bạn vứt bỏ các đối tượng.

2

Loại tùy thuộc vào cách mã gọi điện thoại sẽ sử dụng dữ liệu.

Nếu bạn đang thực hiện ràng buộc dữ liệu đơn giản, thực sự không quan tâm đến loại (nghĩa là bạn không phải truy cập rõ ràng thuộc tính trong mã C#), bạn có thể chuyển kết quả trở lại dưới dạng IEnumberable.

Trong hầu hết các trường hợp dữ liệu bạn gọi các thuộc tính theo tên, thông qua các chuỗi ma thuật, dù sao, vì vậy loại chính xác không quan trọng.

Nếu không, bạn cần phải chuyển đổi loại ẩn danh thành loại được đặt tên.

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