2016-12-29 58 views
3

在下面的C#版本運行時運行下面的代碼的F#版本時出現錯誤。關於如何使用F#從linq查詢返回多個documentdb屬性的任何想法?如何使用DocumentDb,LINQ和F#返回多個屬性?

2016-12-29T23:57:08.504 Exception while executing function: Functions.GetTags. mscorlib: Exception has been thrown by the target of an invocation. mscorlib: One or more errors occurred. Microsoft.Azure.Documents.Client: Constructor invocation is not supported.  

C#

var userTagsQuery = 
    userDocument.Where(user => user.topics != null && user.education != null) 
    .Select(user => new {topics=user.topics, education=user.education}); 

F#

type UserTagRecord = {topics : string list; education : string list} 
    let userTagsQuery = 
    user.Where(fun user -> user.topics <> null && user.education <> null) 
    .Select(fun user -> {topics=user.topics :?> string list; education=user.education :?> string list}) 
+0

我還沒有做任何與documentDB,但也許動態可以幫助你一點? 'FSharp.Interop.Dynamic'和'System.Linq.Dynamic'。然後再次,也許不是... – s952163

回答

2

錯誤說 「不支持構造函數調用」。這是一個明智的限制,大多數LINQ提供商擁有它。

在您的F#代碼中,構造函數調用是創建記錄。 F#記錄被編譯爲具有一堆只讀屬性的類和一個將這些屬性的值作爲參數的單個構造函數。根據錯誤消息,不支持調用此構造函數。厄運。

有趣的是,C#匿名類型(在您的C#代碼中使用)以與F#記錄完全相同的方式工作 - 它們是具有一堆只讀屬性和一個構造函數的類 - 然而,他們受到支持。對於LINQ提供者來說,將C#匿名類型作爲特殊情況處理也是一種常見的做法。許多LINQ提供者會以更通用的方式處理它,這將覆蓋F#記錄,但在這種情況下,顯然不是這種情況。如果我是你,我會開一個關於它的問題。

你可以嘗試什麼是與可變屬性的類取代你的記錄,並與物業初始化語法構造它:

type UserTagRecord() = 
    member val topics : string list = [] with get, set 
    member val education : string list = [] with get, set 

let userTagsQuery = 
    user 
     .Where(fun user -> user.topics <> null && user.education <> null) 
     .Select(fun user -> UserTagRecord(topics=user.topics :?> string list, education=user.education :?> string list)) 

我還要出去肢體這裏建議大家可能進一步有使用F#列表的麻煩。首先,DocumentDb可能不喜歡它們,其次,我不知道user.topicsuser.education是什麼,但我很確定它們不是string list的子類,所以你的演員可能會失敗。

+1

感謝Fyodor的回覆,它提供了有關F#記錄的信息,並且有助於解決問題。我用[]屬性註釋了我的User類,因爲主題和教育屬性可以爲null。我將這些屬性初始化爲null。這允許我基於user.topics <> null && user.education <> null進行過濾,因爲字符串列表不支持null。然後,我從obj轉向字符串列表。使用簡化的UserTagRecord實現您的解決方案,只添加主題並刪除Where子句及其相關的投射要求 –

+0

我得到一個新的和不同的錯誤2016-12-30T01:46:11.710執行function:Functions.GetTags時出現異常。 mscorlib:異常已被調用的目標拋出。無法將以下F#引用轉換爲LINQ表達式樹 -------- 順序(值(), PropertySet(Some(returnVal),topics, [PropertyGet(Some (用戶),主題,[])])), returnVal) –

+0

讓我澄清,[]屬性用於規避此錯誤類型'字符串列表'沒有'null'作爲適當的值當使用Where子句 –