2013-02-28 1 views
1

WCF 데이터 서비스 5.3.0을 리플렉션 데이터 공급자와 함께 사용합니다. 내 원본 데이터가 RavenDB에 저장되어 있으므로 모든 쿼리가 지연됩니다. 그래서, OData 필터를 적용한 후 결과가 클라이언트에 반환되기 전의 내 쿼리에 대해 .ToList()를 호출하는 몇 가지 방법이 있습니까?RavenDB를 WCF Data Services와 함께 사용하려면 어떻게해야합니까?

UPDATE :

public IQueryable<PositionModel> Positions 
    { 
     get 
     { 
      using (var session = OLAPDocumentStore.OpenSession()) 
      { 
       return session 
        .Query<ConsolidatedApplicationPosition>() 
        .Select(x => new PositionModel 
            { 
             ApplicationId = x.ApplicationId, 
             CategoryId = x.CategoryId, 
             ID = x.Id, 
             Platform = x.Platform, 
             Position = x.Position, 
             RegionalCode = x.RegionalCode, 
             Timestamp = x.Timestamp, 
             TopListId = x.TopListId 
            }) 
        .AsQueryable(); 
      } 
     } 
    } 

솔루션은 매트 - 존슨 답변을 @ 참조 및 모델의 모든 속성에 [DataMember를] 추가하는 것을 잊지 마세요 내 DataModel이 속성 선언

[DataContract, DataServiceKey("Id")] 
public class PositionModel 
{ 
    [DataMember] 
    public string Id { get; set; } 
    [DataMember] 
    public string ApplicationId { get; set; } 
    [DataMember] 
    public string CategoryId { get; set; } 
    [DataMember] 
    public int Position { get; set; } 
    [DataMember] 
    public string RegionalCode { get; set; } 
    [DataMember] 
    public DateTime Timestamp { get; set; } 
    [DataMember] 
    public string TopListId { get; set; } 
} 
+0

OData에는 의도적으로 지연되는 'IQueryable'이 필요합니다. 보다 구체적인 대답을 원한다면 몇 가지 코드를 보여주십시오. –

+0

일부 소스 코드로 질문을 업데이트했습니다. –

+0

'.AsQueryable()'은 여기서 중복됩니다. 그만 둘 수 있습니다. 질문의 다른 부분이 있었습니까? 나는 네가하고 싶은 것을 확신하지 못한다. 작동하지 않는 것은 무엇입니까? –

답변

2

좋아, 나는 WCF 데이터 서비스가 어떻게 작동하는지 기억을 되살려 야했다. Shawn Wildermuth는 an excellent example video입니다.

가장 큰 문제는 Select 문을 사용하여 클라이언트 쪽 쿼리를 변환하려고하는 것입니다. IQueryable을 반환하면 linq 공급자 (이 경우에는 RavenDB 쿼리의 출력)에 직접 연결됩니다. WhereOrderBy 필터를 적용 할 수 있지만 Select 문을 사용하여 투영 할 수는 없습니다. 이로 인해 쿼리 체인이 손상됩니다.

따라서 데이터베이스에있는 ConsolidatedApplicationPosition 개체를 WCF Data Services에 반환하는 PositionModel 개체로 투영하려면 다른 방법으로해야합니다. 다음은 몇 가지 옵션이 있습니다 : 당신이 예상 필요한 모든 필드가 소스 데이터에 이미있는 경우

  1. , 당신은 다만 할 수 있습니다

    return session.Query<ConsolidatedApplicationPosition>() 
           .AsProjection<PositionModel>(); 
    

    여기에 유일한 문제는 당신의 식별자 그 돈은 일치하지 마. Raven의 기본 식별자 규칙은 Id (파스칼 케이스)이며 WCF는 ID (대문자)입니다.

    DocumentStore.Conventions.FindIdentityProperty = x => x.Name == "ID"; 
    

    또는 DataServiceKey 속성으로 WCF의 규칙을 변경하여 : 당신은 까마귀의 규칙을 변경하여 중 하나를 줄 수 있습니다 당신이 원하는 경우 일치하지 않는 식별자를 유지하려는 경우 또는

    [DataContract, DataServiceKey("Id")] 
    public class PositionModel 
    { 
        [DataMember] 
        public int Id { get; set; } 
    
        ... 
    } 
    
  2. 더 많은 필드를 변환하면 동적 색인을 사용할 수 없습니다. 대신, 정적 인덱스를 생성해야하고 투사 제어하기 위해 변환 용도 것이다 : 당신이 장소에 인덱스를 설정 한 후

    public class YourIndex : AbstractIndexCreationTask<ConsolidatedApplicationPosition> 
    { 
        public YourIndex() 
        { 
        Map = docs => 
         from doc in docs 
         select new 
         { 
         // You need to map any fields that you might query 
         // or sort on through the odata filters. 
         }; 
    
        TransformResults = (database, docs) => 
         from doc in docs 
         select new PositionModel 
         { 
         // if you need integer identifiers in your result, 
         // you'll have to split them from the doc key, like this: 
         ID = int.Parse(doc.Id.ToString().Split('/')[1]), 
    
         // otherwise, just do this: 
         ID = doc.Id, 
    
         // bring over all of your other fields as well 
         Platform = doc.Platform 
         ... etc ... 
    
        }; 
        } 
    } 
    

    을, 당신은 이런 식으로 쿼리를 다음과 같습니다

    return session.Query<PositionModel, YourIndex>(); 
    

어느 옵션을 사용하더라도 쿼리에 select 문이 없으므로 ToList 또는 AsQueryable을 수행 할 필요가 없습니다. RavenDB linq 공급자의 IQueryable 인터페이스를 WCF Data Service 컨텍스트로 보내기 만하면됩니다.

+0

RavenDB 2.5 (아직 출시되지 않음)의 인덱스에서 변환을 분리하려고합니다. 정적 인덱스를 만드는 대신 동적 인덱스에 대해 변환을 수행 할 수 있습니다. [자세한 내용은 여기를 참조하십시오.] (https://groups.google.com/d/topic/ravendb/w9Diy8ub5OM/discussion) –

+0

장난감을 보내 주셔서 감사합니다. 매우 유용합니다. 하지만 내 문제는 달라졌다 (업데이트 된 요새) –

+0

@ JiříGluškov 응? 나는 당신이 물어 본 것에 직접 대답했습니다 ... –