2010-03-15 144 views
5

我想在使用LINQ(特別是,LINQ到實體)時實現MVC。我會這樣做的方式是讓Controller使用LINQ生成(或調用生成的)結果集,然後將其返回給View以顯示數據。問題是,如果我這樣做:簡單的方法來返回匿名類型(使MVC使用LINQ可能)

return (from o in myTable select o); 

所有的列從數據庫中讀取,即使我不希望那些(潛在的幾十個)。而且 - 更重要的是 - 我無法做這樣的事情:

return (from o in myTable select new { o.column }); 

因爲沒有辦法使匿名類型的類型安全的!我知道肯定沒有很好,乾淨的方式做到這一點在3.5(this不乾淨...),但4.0呢?有沒有計劃,甚至提出?沒有像LINK或者類型安全的匿名返回值這樣的東西(在我看來,編譯器當然應該可以做到這一點),似乎幾乎不可能將Controller從View中分離出來。

+0

當您使用orm時,您應該習慣於讓sql選擇表的所有列。如果您編寫的查詢只選擇少數幾個,那麼您最好還是先使用sql。如果你的對象有幾十個屬性,那就是你的問題。你的物體應該更小,你應該考慮如何解決這個問題。匿名類型不應該被傳遞,特別是不作爲視圖的模型。 – 2010-03-17 07:26:38

+0

@Mattias:不幸的是,生活並不那麼簡單。例如,考慮從不同表中選擇幾列的情況,包括使用內部LINQ查詢選擇的對象數組。據我所知,沒有辦法將它作爲單個EF對象返回 - 它*具有*爲新類型,並且爲每個這樣的查詢定義新的具體類型是非常麻煩的。 – 2010-03-17 13:26:51

+0

聽起來像你有一個非常糟糕的模型。你的對象應該有它需要的引用,你可以在EF中使用「Include()」方法(以便加載這些數據)。如果您不再將數據視爲不同表格中的不同列,並且更多地關注您的模型(更多面向對象),它很可能會更容易處理。底線:如果你覺得需要傳遞匿名類型,你很可能會做其他事情。 – 2010-03-17 14:02:21

回答

1

既然沒有人甚至企圖回答我的問題,我會回答它自己..

事實證明,C#4.0支持鴨打字 - 他們稱之爲dynamic typing。然而,在使用動態類型的返回匿名類型,我們失去了強類型的好處:

  • 編譯時的類型檢查
  • 性能
  • 智能感知

我已經開了功能請求具有強類型的匿名返回類型here - 如果您認爲這將對C#5有用,那麼請按照鏈接並讓.NET團隊知道!

3

匿名類型主要用於在方法中使用。它們不適合方法之間的通信。

如果你需要先通過一組數據的兩個功能之間的最佳方法是創建一個新的類型包裝的數據,或使用一個失敗者分組像Tuple<T1,T2>KeyValuePair<TKey,TValue>

+0

除了基於反射的場景外,在這種情況下,他們有一些很好的用處(例如在MVC框架中,html幫助器) – 2010-03-15 21:20:45

+0

@Jared:除LINQ之外,根本不是這樣 - LINQ對象肯定是要傳遞的,但是由於語言的限制,你不能用C#來完成。然而,它*可以在VB.net中完成。 – 2010-03-15 21:24:57

+0

@BlueRaja,對不起,這是不正確的。他們**可以**作爲'System.Object'以任何一種語言傳遞。由於匿名類型是匿名的,因此不能以任何一種語言強烈傳播。它們不能直接定義在任何會出現在元數據中的地方。在VB.net(和C#4.0)中,您可以通過以弱類型訪問它們來解決此問題,但這不是OP所要求的。 – JaredPar 2010-03-15 21:28:22

4

使用視圖模型層。你的觀點必須知道它將要顯示的內容。我想它可能會創建一個視圖,只是格式化多維數據數組,但這不完全是MVC解決方案的最佳理由。但是,您可以使用匿名對象填充視圖模型,以便在視圖中使用。

2

這個怎麼樣?我爲什麼不實例化一個新的MyTableEntity對象並使用對象初始值設定項來只填充你想要的那些列?爲什麼你不實例化一個新的MyTableEntity對象並使用對象初始值設定項來填充你想要的那些列?爲什麼不實例化一個新的MyTableEntity對象?

return (from o in myTable select new MyTableEntity { AColumn = o.column }); 

這不會轉化爲一個SELECT *,你問,但你仍然有辦法一個強類型的對象傳遞給視圖。

你必須小心使用視圖內的初始化屬性,就是這樣。

這對你有意義嗎?

+0

這是一個好主意 - 當我有機會時,我會在工作中嘗試一下(至少不是幾天) – 2010-04-27 00:28:40

0

在.NET 4.0上匿名類型可以很容易地轉換爲ExpandoObjects,因此所有問題都可以通過轉換本身的開銷來解決。 退房here

0

您可以輕鬆地將匿名類型轉換爲動態的對象,下面是簡單的實現Donymous對象(動態匿名對象),可以從匿名對象或DataReader的填充的。