2013-08-21 3 views
1

나는 다음과 같은 두 개의 클래스 정의가 다음과 같이 내가 인덱스가 정의ravendb 쿼리 locationsbyip 인덱스

public class Location : Doc 
{ 
    public string Country { get; set; } 
    public string Region { get; set; } 
    public string City { get; set; } 
    public string PostalCode { get; set; } 
    public Double Latitude { get; set; } 
    public Double Longitude { get; set; } 
    public string MetroCode { get; set; } 
    public string AreaCode { get; set; } 
    public List<IpRange> IpRanges { get; set; } 
} 

public class IpRange 
{ 
    public long Start { get; set; } 
    public long End { get; set; } 
} 

을 :

public class Locations_ByRange : AbstractIndexCreationTask<Location> 
{ 
    public Locations_ByRange() 
    { 
     Map = locations => 
      from location in locations 
      from range in location.IpRanges 
      select new 
      { 
       range.Start, 
       range.End 
      }; 
    } 
} 

그때 쿼리 시도 다음과 같은 색인 :

var queryable = DocumentSession.Query<IpRange, Locations_ByRange>() 
         .FirstOrDefault(x => x.Start <= reverseIp && x.End >= reverseIp) ?? new IpRange(); 

하지만, 쿼리를 실행할 때 다음과 같은 오류를 만나 오전 :

[InvalidCastException: Unable to cast object of type 'Jodolo.Data.Locations.Location' to type 'Jodolo.Data.Locations.IpRange'.] 
    Raven.Client.Document.InMemoryDocumentSessionOperations.TrackEntity(String key, RavenJObject document, RavenJObject metadata, Boolean noTracking) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:357 
    Raven.Client.Document.SessionOperations.QueryOperation.Deserialize(RavenJObject result) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\SessionOperations\QueryOperation.cs:167 
    System.Linq.WhereSelectListIterator`2.MoveNext() +104 
    System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +381 
    System.Linq.Enumerable.ToList(IEnumerable`1 source) +58 
    Raven.Client.Document.SessionOperations.QueryOperation.Complete() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\SessionOperations\QueryOperation.cs:143 
    Raven.Client.Document.AbstractDocumentQuery`2.GetEnumerator() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\AbstractDocumentQuery.cs:891 
    System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) +152 
    Raven.Client.Linq.RavenQueryProviderProcessor`1.GetQueryResult(IDocumentQuery`1 finalQuery) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Linq\RavenQueryProviderProcessor.cs:1529 
    Raven.Client.Linq.RavenQueryProviderProcessor`1.ExecuteQuery() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Linq\RavenQueryProviderProcessor.cs:1454 
    Raven.Client.Linq.RavenQueryProviderProcessor`1.Execute(Expression expression) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Linq\RavenQueryProviderProcessor.cs:1427 
    Raven.Client.Linq.RavenQueryProvider`1.Execute(Expression expression) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Linq\RavenQueryProvider.cs:155 
    Raven.Client.Linq.RavenQueryProvider`1.System.Linq.IQueryProvider.Execute(Expression expression) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Linq\RavenQueryProvider.cs:198 
    System.Linq.Queryable.FirstOrDefault(IQueryable`1 source, Expression`1 predicate) +287 

: 여기,

Exception Details: System.InvalidCastException: Unable to cast object of type 'Jodolo.Data.Locations.Location' to type 'Jodolo.Data.Locations.IpRange'. 

을 그리고는 스택 트레이스입니다. . .

궁극적으로 쿼리 매개 변수를 만족하는 위치 문서를 검색하려고하기 때문에이 것을보기가 다소 기쁩니다. 내가

.Query<Location, Locations_ByRange>() 

에 쿼리 통화 유형 선언을 변경할 수 있습니다 그러나, 그때 문제가 인덱스에 저장 필드를 쿼리하는 방법을 알아내는이 분명하다; Location 객체에 대해 정의 된 Start 및 End 필드가 없기 때문입니다.

이 문제에 도움을 주시면 매우 감사하겠습니다.

답변

1
가 쿼리를 변경

: 색인에서

using Raven.Client; 

... 

var location = session.Query<IpRange, Locations_ByRange>() 
         .Where(x => x.Start <= reverseIp && x.End >= reverseIp) 
         .As<Location>() 
         .FirstOrDefault(); 

, 당신은 정렬 힌트를 추가해야 할 수 있습니다 : 나는 AbstractIndexCreationTask<Location, IpRange>에서 상단의 반환 유형을 추가

public class Locations_ByRange : AbstractIndexCreationTask<Location, IpRange> 
{ 
    public Locations_ByRange() 
    { 
     Map = locations => 
      from location in locations 
      from range in location.IpRanges 
      select new 
      { 
       range.Start, 
       range.End 
      }; 

     Sort(x => x.Start, SortOptions.Long); 
     Sort(x => x.End, SortOptions.Long); 
    } 
} 

참고. 이렇게하면 Sort 메서드에서 해당 속성을 찾을 수 있도록 유형을 정렬합니다.

+0

내가 지정한대로 쿼리를 변경하면 빌드 할 수 없습니다. 클래스에 추가해야하는 사용 문이 있습니까? –

+0

Raven.Client.Linq에 using 지시문을 추가했지만 여전히 운이 없습니다. 음 ... –

+0

정렬 힌트를 추가하기 위해 색인을 수정하는 방법에 대한 업데이트 된 답변을 참조하십시오. 그것들이 없다면, 그 필드들은 아마도 문자열 정렬과 범위 쿼리를 던지면서 정렬 될 것입니다. –