2017-02-01 1 views
0

내가 특정 개체 유형의 documentdb에서 문서 목록을 얻으려고 -DocumentDb CreateDocumentQuery <T> 반환 항목

_client.CreateDocumentQuery<RuleSetGroup>(_collectionLink) 
      .Where(f => f.SourceSystemId == sourceSystemId).AsEnumerable().ToList(); 

이는만큼, RuleSetGroup가 아닌 다른 유형의 객체를 반환 그들은 내가 전달하는 것과 일치하는 SourceSystemId 속성을 가지고 있습니다. 나는 documentdb가 어떻게 작동하는지 이해하고 있습니다. 타입 T를 적용 할 수있는 방법이 있습니다. 그래서 그 객체들만 반환됩니다.

내가 사용하고 자동 형식 처리 :

JsonConvert.DefaultSettings =() => new JsonSerializerSettings() 
       { 
        TypeNameHandling = TypeNameHandling.Auto 
       }; 

답변

1

유형 패턴 (각 클래스에 유형 속성 추가)을 구현하고 추가 필터로 사용하지 않는 한 다른 문서 유형이 제공됩니다.

이유는 분명히 스키마가 다를 수있는 NoSQL 문서를 저장하기 때문입니다. DocumentDB는 모든 것을 동등하게 취급합니다. 모든 문서입니다. 쿼리 할 때 다른 문서 유형을 구분하는 것은 사용자의 책임입니다 (차이점 만 알기 때문에).

유형이 모두 "클라이언트"(예 : 주문 및 청구서) 인 경우 해당 속성으로 쿼리를 작성하지만 하나의 유형 (주문)에 매핑하면 주문과 송장이 모두 일치합니다 필터는 쿼리와 일치하는 문서이므로 deserialization 논리는 DocDB가 아닌 사용자의 목적에 부합합니다.

Here is an article DocDB에 다른 문서 유형을 저장할 때 해당 유형 패턴과 관련됩니다 (기본 유형 패턴 섹션 확인). 이 같은

뭔가를 해결할 수 있습니다

public abstract class Entity 
{ 
    public Entity(string type) 
    { 
     this.Type = type; 
    } 
    /// <summary> 
    /// Object unique identifier 
    /// </summary> 
    [Key] 
    [JsonProperty("id")] 
    public string Id { get; set; } 
    /// <summary> 
    /// Object type 
    /// </summary> 
    public string Type { get; private set; } 
} 

public class RuleSetGroup : Entity 
{ 
    public RuleSetGroup():base("rulesetgroup") 

} 

public class OtherType : Entity 
{ 
    public OtherType():base("othertype") 

} 

_client.CreateDocumentQuery<RuleSetGroup>(_collectionLink).Where(f => f.Type == "rulesetgroup" && f.SourceSystemId == sourceSystemId).AsEnumerable().ToList(); 

당신은 다른 필터를 적용하기 전에 Where 절 같은 종류를 설정 도우미에서 쿼리를 포장 할 수 있습니다 (LINQ에서 할 수 있습니다 문제없이 체인 알의).

+0

오브젝트의 유형을 설정하는 아이디어를 확장합니다. 수동으로하기보다는 기본 클래스를 상속하는 객체의 이름을 제공하는 기본 클래스 (위의'Entity')에서'public string Type => this.GetType(). Name;'을 할 수 있습니다 ('RuleSetGroup '및'OtherType' 위) – Dezzamondo

1

내 저장소 당신을 위해 많은에 조금있을 수 있습니다, 짧은 대답 대신

public async Task<IEnumerable<T>> GetDocumentsAsync<T>(Expression<Func<T, bool>> predicate, int maxReturnedDocuments = -1, 
     bool enableCrossPartitionQuery = true, int maxDegreeOfParallellism = -1, int maxBufferedItemCount = -1) 
    { 
     //MaxDegreeofParallelism default = 0, add -1 to let SDK handle it instead of a fixed 1 network connection 
     var feedOptions = new FeedOptions 
     { 
      MaxItemCount = maxReturnedDocuments, 
      EnableCrossPartitionQuery = enableCrossPartitionQuery, 
      MaxDegreeOfParallelism = maxDegreeOfParallellism, 
      MaxBufferedItemCount = maxBufferedItemCount 
     }; 

     IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
     UriFactory.CreateDocumentCollectionUri(_databaseName, _collectionName), feedOptions) 
     .Where(predicate) 
     .AsDocumentQuery(); 

     List<T> results = new List<T>(); 
     while (query.HasMoreResults) 
     { 
      var res = await query.ExecuteNextAsync<T>(); 
      results.AddRange(res); 
     } 
     return results; 
    } 
ToList()의) .AsDocumentQuery를 (반환 할 수있다

은이 같은 상기 방법을 호출 할 수 VAR의 ecsterConfigs의이 repoBO.GetDocumentsAsync = (c => c.ValidTo == 널 & & c.Type == 타입) 기다리고;

그리고 나서 문서의 업데이트를 "할"때 문서를 업데이트 할 때 변경 될 _Etag를 추적하기 위해 래퍼가 있습니다.

public class DocumentWrapper<DocumentType> 
{ 
    public DocumentWrapper(Document document) 
    { 
     Value = (DocumentType)(dynamic)document; 
     ETag = document.ETag; 
     TimeStamp = document.Timestamp; 
    } 
    public DocumentType Value { get; set; } 
    public string ETag { get; set; } 
    public DateTime TimeStamp { get; set; } 
} 
+0

이 나를 위해 작동하지 않습니다 - 난 아직도 ... –

+0

안녕하세요, 참조, 내가 가지고있는 모든 문서를 다시 얻을 수를 내 모든 유형에 대한 typeName은 DocDb로 전송 된 where 문에서 올바른 유형을 얻습니다. c => c.typeName == "yourType"그래서 모든 doamin 유형의 네임 스페이스를 포함하여 fullName을 추가합니다. – Granlund

+0

@Granlund - 예제 코드에 GetDocumentsAsync에 대한 한 줄 예제 호출이 포함되어 있으면 훌륭한 대답이 될 것입니다. camelCase

0

@Granlund 어떻게 GetDocumentsAsync가 DocumentWrapper 인스턴스를 반환하면서도 술어가 값의 속성을 쿼리 할 수있게합니까? 여기

내가 생각 해낸 것입니다하지만 어쩌면 당신은 더 좋은 방법이 있습니다

[TestMethod] 
    [TestCategory("CosmosDB.IntegrationTest")] 
    public async Task AddAndReadDocumentWrapperViaQueryAsync() 
    { 
     var document = new Foo { Count = 1, Name = "David" }; 
     var response = await client.CreateDocumentAsync(documentCollectionUri, document); 

     var id = response.Resource.Id; 

     var queryResult = await GetWrappedDocumentsAsync<Foo>(f => f.Where(a => a.Name == "David")); 

     foreach (var doc in queryResult) 
     { 
      Assert.AreEqual("David", doc.Value.Name); 
     } 
    } 

    public class Foo 
    { 
     public int Count { get; set; } 

     public string Name { get; set; } 
    } 

    public class DocumentWrapper<DocumentType> 
    { 
     public DocumentWrapper(Document document) 
     { 
      Value = (DocumentType)(dynamic)document; 
      ETag = document.ETag; 
      TimeStamp = document.Timestamp; 
     } 

     public DocumentType Value { get; set; } 

     public string ETag { get; set; } 

     public DateTime TimeStamp { get; set; } 
    } 

    public async Task<IEnumerable<DocumentWrapper<T>>> GetWrappedDocumentsAsync<T>(
     Func<IQueryable<T>, IQueryable<T>> query, 
     int maxReturnedDocuments = -1, 
     bool enableCrossPartitionQuery = true, 
     int maxDegreeOfParallellism = -1, 
     int maxBufferedItemCount = -1) 
    { 
     //MaxDegreeofParallelism default = 0, add -1 to let SDK handle it instead of a fixed 1 network connection 
     var feedOptions = new FeedOptions 
     { 
      MaxItemCount = maxReturnedDocuments, 
      EnableCrossPartitionQuery = enableCrossPartitionQuery, 
      MaxDegreeOfParallelism = maxDegreeOfParallellism, 
      MaxBufferedItemCount = maxBufferedItemCount 
     }; 

     IDocumentQuery<T> documentQuery = 
      query(client.CreateDocumentQuery<T>(documentCollectionUri, feedOptions)).AsDocumentQuery(); 

     var results = new List<DocumentWrapper<T>>(); 
     while (documentQuery.HasMoreResults) 
     { 
      var res = await documentQuery.ExecuteNextAsync<Document>(); 

      results.AddRange(res.Select(d => new DocumentWrapper<T>(d))); 
     } 

     return results; 
    } 
+0

이 질문에 대한 답변을 제공하지 않습니다. [비슷한 질문을 검색] (// stackoverflow.com/search)하거나 페이지의 오른쪽에있는 관련 및 연결된 질문을 참조하여 대답을 찾을 수 있습니다. 관련이 있지만 다른 질문이있는 경우 [새 질문하기] (// stackoverflow.com/questions/ask)를 읽고 컨텍스트를 제공하는 데 도움이되는 링크를 포함하십시오. 참조 : [질문하기, 대답하기, 산만하게하기] (// stackoverflow.com/tour) – Bugs

+0

이것은 실제로 질문에 대답하지 않습니다. 다른 질문이있는 경우 [질문하기] (https://stackoverflow.com/questions/ask)를 클릭하여 질문 할 수 있습니다. [평판] (https://stackoverflow.com/help/privileges/set-bounties)을 충분히 확보하면 [현상금 추가] (https://stackoverflow.com/help/privileges/set-bounties)를 통해이 질문에 더 집중할 수 있습니다. 평판). - [리뷰에서] (리뷰/저품절 게시물/17889649) –