2008-10-21 37 views
39

Tôi vừa mới bắt đầu làm việc với ASP.NET MVC bây giờ là bản beta. Trong mã của tôi, tôi đang chạy một truy vấn LINQ to SQL đơn giản để có được một danh sách các kết quả và chuyển nó tới khung nhìn của tôi. Loại điều này:Tôi có thể chuyển kiểu ẩn danh cho chế độ xem ASP.NET MVC của mình không?

var ords = from o in db.Orders 
      where o.OrderDate == DateTime.Today 
      select o; 

return View(ords); 

Tuy nhiên, trong chế độ xem của tôi, tôi nhận thấy rằng tôi cần truy cập tên của khách hàng cho mỗi đơn đặt hàng. Tôi bắt đầu sử dụng o.Customer.Name nhưng tôi khá chắc chắn rằng điều này là thực hiện một truy vấn riêng biệt cho mỗi đơn đặt hàng (vì tải LINQ của lười biếng).

Cách hợp lý để cắt giảm số lượng truy vấn sẽ là chọn tên khách hàng cùng một lúc. Một cái gì đó như:

var ords = from o in db.Orders 
      from c in db.Customers 
      where o.OrderDate == DateTime.Today 
       and o.CustomerID == c.CustomerID 
      select new { o.OrderID, /* ... */, c.CustomerName }; 

return View(ords); 

Ngoại trừ bây giờ biến "ords" của tôi là IEnumerable của một loại ẩn danh.

Có thể khai báo chế độ xem ASP.NET MVC theo cách nó chấp nhận dữ liệu xem của IEnumerable khi T được xác định bởi những gì được truyền từ bộ điều khiển hay tôi phải xác định loại cụ thể điền từ truy vấn của tôi?

Trả lời

22

Bạn có thể chuyển nó đến chế độ xem không? Có, nhưng chế độ xem của bạn sẽ không được đánh máy mạnh. Nhưng những người giúp việc sẽ làm việc. Ví dụ:

public ActionResult Foo() { 
    return View(new {Something="Hey, it worked!"}); 
} 

//Using a normal ViewPage 

<%= Html.TextBox("Something") %> 

Hộp văn bản đó sẽ hiển thị "Xin chào!" làm giá trị.

Vì vậy, bạn có thể xác định chế độ xem trong đó T được xác định bởi những gì được truyền cho nó từ bộ điều khiển không? Vâng vâng, nhưng không phải lúc biên dịch rõ ràng.

Hãy suy nghĩ về nó trong giây lát. Khi bạn khai báo một kiểu mô hình cho một khung nhìn, nó là để bạn có được intellisense cho khung nhìn. Điều đó có nghĩa là loại phải được xác định tại thời gian biên dịch. Nhưng câu hỏi đặt ra, chúng ta có thể xác định loại từ một cái gì đó được đưa ra cho nó khi chạy. Chắc chắn, nhưng không phải với cách gõ mạnh được bảo toàn.

Làm cách nào để bạn nhận được Intellisense cho loại bạn thậm chí không biết? Bộ điều khiển có thể sẽ chuyển bất kỳ loại nào đến chế độ xem trong khi đang chạy. Chúng tôi thậm chí không thể phân tích mã và đoán, bởi vì bộ lọc hành động có thể thay đổi đối tượng được chuyển đến chế độ xem cho tất cả những gì chúng tôi biết.

Tôi hy vọng làm rõ câu trả lời mà không làm xáo trộn nó nhiều hơn.:)

+0

Nếu có ai biết đó là bạn, Phil. Cảm ơn bạn đã có thể truy cập vào những người như tôi! –

+0

Điều này có trả lời câu hỏi không? Tôi có vấn đề chính xác này và câu trả lời này không giúp được gì. Bạn có thể cho thấy cách chúng ta có thể lặp qua các ords và hiển thị trong một khung nhìn? –

+11

Nó không trả lời câu hỏi! Đáng ngạc nhiên là nó hoạt động cho các hộp văn bản, nhưng nếu tôi muốn chỉ để làm cho giá trị này, làm thế nào để làm điều đó? <% = Model.Something%> không hoạt động, bạn sẽ nhận được 'đối tượng' không chứa định nghĩa cho ngoại lệ 'Cái gì đó'. – PawelRoman

0

bạn có thể chuyển đối tượng và sử dụng phản chiếu để có được kết quả mong muốn. Có một cái nhìn tại ObjectDumper.cs (bao gồm trong csharpexamples.zip) cho một ví dụ về điều này.

+0

Vâng, tôi đã nghĩ rằng việc sử dụng phản chiếu để mở loại vô danh mở và coi nó là Từ điển có thể là giải pháp duy nhất. Bit của một bummer nếu đó là trường hợp. –

0

Nếu tôi không nhầm, các loại ẩn danh được chuyển đổi thành các đối tượng được nhập mạnh vào thời gian biên dịch. Cho dù đối tượng được gõ mạnh có hợp lệ cho dữ liệu xem hay không là một câu hỏi khác.

1

Điều này post cho biết cách bạn có thể trả lại loại ẩn danh từ phương thức nhưng không phù hợp với yêu cầu của bạn.

Một tùy chọn khác có thể thay vì chuyển đổi loại ẩn danh thành JSON (JavaScriptSerializer sẽ làm điều đó) và sau đó trả về JSON đó, bạn sẽ cần một số jQuery vv để làm những gì bạn thích với nó.

Tôi đã sử dụng LINQ để 'định hình' dữ liệu của tôi thành định dạng JSON mà chế độ xem của tôi cần có thành công lớn.

+0

Ý tưởng JSON nghe có vẻ hấp dẫn, nhưng nếu tôi định thêm mã để làm điều đó thì tôi cũng có thể định nghĩa một lớp có thứ tự và thuộc tính khách hàng của tôi trong đó và từ bỏ ý tưởng kiểu ẩn danh. +1 dù sao đi nữa. –

+0

Đồng ý. Kịch bản sử dụng JSON chính của tôi đã trả về một đối tượng JSON từ một cuộc gọi ajax được sử dụng để điền vào một lưới (ví dụ: Flexigrid), lưới yêu cầu dữ liệu theo một định dạng cụ thể, Linq đá giúp tôi định dạng dữ liệu thành định dạng đó. – zadam

4

Đối với những gì đáng giá, tối nay tôi đã phát hiện ra lớp DataLoadOptions và phương thức LoadWith của nó. Tôi đã có thể nói LINQ to SQL DataContext của mình luôn tải hàng của Khách hàng bất cứ khi nào một hàng Đơn hàng được truy xuất, do đó truy vấn ban đầu hiện có mọi thứ tôi cần trong một lần truy cập.

+0

Wow ... Rất cám ơn - Tôi đã tìm kiếm một cách điên cuồng về điều này trong vài giờ qua. Tôi biết nó phải tồn tại nhưng không chắc chắn nơi để tìm. Cảm ơn người đàn ông! –

1

Bạn có thể viết một lớp học có cùng thuộc tính với loại ẩn danh của bạn và bạn có thể truyền loại ẩn danh của mình sang loại viết tay. Hạn chế là bạn phải cập nhật lớp khi bạn thực hiện các thay đổi chiếu trong truy vấn LINQ của mình.

+1

Sau đó, hoàn toàn đánh bại mục đích sử dụng một loại ẩn danh từ phương thức hành động. Tại thời điểm đó, bạn cũng có thể chỉ cần trả về một cá thể lớp. – Peter

0

Tôi đang gặp vấn đề tương tự ... sau khi suy nghĩ một chút, tôi đi đến kết luận rằng giải pháp chính xác nhất và có khả năng mở rộng nhất, để sắp xếp từng loại ẩn danh này trước khi gửi tới Chế độ xem. Vì vậy, bạn có thể sử dụng cùng một phương pháp để điền vào trang bằng cách sử dụng mã Xem phía sau và để điền trang của bạn bằng cách sử dụng JSON

11

Bạn có thể chuyển các loại ẩn danh này sang chế độ xem.

Bạn có thể làm như thế này:

return View(new { 
    MyItem = "Hello", 
    SomethingElse = 42, 
    Third = new MyClass(42, "Yes") }) 

Ở phía trên của quan điểm thì bạn có thể làm điều này (sử dụng dao cạo ở đây)

@{ 
    string myItem = (dynamic)Model.MyItem; 
    int somethingElse = (dynamic)Model.SomethingElse; 
    MyClass third = (dynamic)Model.Third; 
} 

Hoặc bạn có thể quăng từ ViewData như thế này :

@{ 
    var myItem = ViewData.Eval("MyItem") as string 
    var somethingElse = ViewData.Eval("SomethingElse") as int? 
    var third = ViewData.Eval("Third") as MyClass 
} 
+7

Vâng, ví dụ đầu tiên của bạn không hoạt động. Ít nhất không phải trong MVC3. Sự ngạc nhiên! Trước hết, trong chế độ xem không được phân loại, 'Mô hình' đã là' động', không cần truyền. Và thứ hai, với mã của bạn, tôi nhận được một 'RuntimeBinderException' với thông điệp" * 'đối tượng' không chứa một định nghĩa của MyItem * ". Bất kỳ ý tưởng? –

+5

Tôi vừa mới giải thích. Hóa ra, các kiểu ẩn danh là nội bộ, có nghĩa là các thuộc tính của chúng không thể được nhìn thấy bên ngoài hội đồng định nghĩa của chúng. Hãy xem tại đây: http://www.gregshackles.com/2010/09/anonymous-view-models-in-asp-net-mvc-using-dynamics/ –

6

Trên .NET 4.0 Các loại ẩn danh có thể dễ dàng được chuyển đổi thành ExpandoObject và do đó tất cả điều khiển ems được cố định với chi phí của chính chuyển đổi. Kiểm tra here

3

Here là một bài viết giải thích về việc chuyển loại Chưa xác định thành Chế độ xem và ràng buộc dữ liệu.

Cảm ơn

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