2016-12-29 7 views
3

아래 C# 버전이 작동하는 동안 아래 코드의 F # 버전을 실행할 때 오류가 발생합니다. 모든 아이디어를 linq 쿼리에서 여러 documentdb 속성을 반환하는 방법에 대한 F # 일반적으로?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#을

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

오류가 "생성자 호출이 지원되지 않습니다"라는

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

F 번호. 이것은 현명한 한계이며 대부분의 LINQ 제공 업체가 가지고 있습니다.

F # 코드에서 생성자 호출은 레코드 생성입니다. F # 레코드는 일련의 읽기 전용 속성과 이러한 속성의 값을 매개 변수로 취하는 단일 생성자가있는 클래스로 컴파일됩니다. 오류 메시지에 따르면이 생성자를 호출하는 것은 지원되지 않습니다. 불행.

주목할 점은 C# 코드에 사용 된 C# 익명 형식이 F # 레코드와 정확히 똑같은 방식으로 작동한다는 것입니다. 이들은 읽기 전용 속성과 단일 생성자가있는 클래스이며, 그들은 지원됩니다. C# 익명 형식을 특별한 경우로 취급하는 것은 LINQ 공급자에게 일반적인 관행입니다. 많은 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 # 레코드뿐만 아니라 문제 해결에 도움이됩니다. 주제 및 교육 속성이 null 일 수 있기 때문에 [] 속성으로 내 User 클래스에 주석을 추가했습니다. 이러한 속성을 null로 초기화합니다. 이렇게하면 string.txt가 null을 지원하지 않기 때문에 user.topics <> null && user.education <> null을 기반으로 필터링 할 수 있습니다. obj에서 문자열 목록으로 다운 캐스트합니다. 토픽만으로 단순화 된 UserTagRecord로 솔루션 구현 및 Where 절 제거 및 관련 캐스팅 요구 사항 –

+0

2016-12-30T01 : 46 : 11.710 함수를 실행하는 동안 예외가 발생했습니다. Functions.GetTags. mscorlib : 호출 대상에 의해 예외가 발생했습니다. FSharp.Core : 다음 F # 견적을 LINQ 식 트리로 변환 할 수 없습니다. -------- 순차 (순차 값 (), PropertySet (일부 (returnVal), 주제, [PropertyGet (일부 (사용자), 주제, [])])), returnVal) –

+0

[] 특성이이 오류를 우회하는 데 사용된다는 점을 분명히하자. 'string list'유형에 적절한 값으로 'null'이 없습니다. Where 절을 사용할 때 –