2011-08-26 4 views
2

대답 :이 질문에 대한 내 대답을 찾으려면 아래로 이동하십시오.SharePoint OData 서비스를 쿼리 할 때 LINQ의 날짜 비교 사용

LINQ를 사용하여 ASP.NET MVC 3 프로젝트에서 SharePoint 2010 OData를 사용하려고합니다. Razor 뷰 엔진 (VS 2010)과 함께 ASP.NET MVC 3 프로젝트 템플릿을 사용하여 기본 프로젝트를 만들었습니다. SharePoint 2010 사이트를 가리키는 서비스 참조를 추가했습니다.

내 HomeController의 Index 메서드 (이것은 단지 테스트 프로젝트 임)에서 컨텍스트를 보유하고 컨텍스트 변수의 Credentials 속성을 현재 기본 자격 증명으로 설정하는 변수를 만들었습니다.

다음과 같은 링크 쿼리가 잘 작동하고 내가 어떤 데이터에 액세스하기 위해 만든 변수를 사용할 수 있습니다 : SharePoint 사이트에서

이 쿼리는 단순히 목록에서 공지 사항을 모두 얻을 수

var query = from a in context.Alerts 
      select a; 
라는 경고 . 이 목록에는 제목, 내용, 시작 날짜 및 만료 날짜 필드가 있습니다. 내가 다음에 쿼리를 변경할 때

, 내가 예상 결과를 얻을하지 않습니다

var query = from a in context.Alerts 
      where (a.Begins < DateTime.Now) 
      select a; 

이 쿼리는 날짜의 시간 구성 요소를 무시합니다. 예를 들어, a.Begins에 어제의 datetime이 포함되어 있으면 쿼리가 AlertItem을 반환합니다. 반면에 a.Begins에 현재 날짜가있는 datetime이 포함되어 있으면 (이전 시간) 비교 결과는 false를 반환하고 a.Begins == DateTime.Now는 true를 반환합니다.

var query = (from a in context.Alerts 
      select a).ToList(); 
var query2 = from q in query 
      where (q.Begins < DateTime.Now) 
      select q; 

내가 무엇을 놓치고 : 다음과 같은 처리를 할 경우

는 두 번째 LINQ 쿼리는 예상대로 작동?

답변

0

다른 소스의 많은 정보를 조립할 후 어느 것도 내가, 나는 다음과 같은 결론에 도달 한 데 문제의 정확한 상황 처리 SharePoint 개체 모델 및 CAML (Collaborative Application Markup Language), SharePoint는 기본적으로 비교를 수행 할 때 DateTime 요소의 시간 구성 요소를 사용하지 않습니다. 다음과 같이, 당신은 값 유형에 IncludeTimeValue = 'TRUE'속성을 포함해야하는 시간 구성 요소를 사용하는 셰어에게 :

<Where> 
<Eq> 
    <FieldRef Name='Begins' /> 
    <Value Type='DateTime' IncludeTimeValue='TRUE'> 
    2008-03-24T12:00:00Z 
    </Value> 
</Eq> 
</Where> 

나는 원인 셰어에 LINQ의 버그를 참조 여러 블로그 게시물을 발견 IncludeTimeValue = 'TRUE'는 소자의 FieldRef 값 대신 요소에 있는지

<Where> 
<Eq> 
    <FieldRef Name='dateTimeField' IncludeTimeValue='TRUE' /> 
    <Value Type='DateTime'> 
    2008-03-24T12:00:00Z 
    </Value> 
</Eq> 
</Where> 

공지 : 생성 CAML 출력에 따른다. 이 속성에 대한 적절한 위치가 아니므로 datetime 비교를 수행하는 모든 LINQ to SharePoint 쿼리가 날짜 구성 요소와 비교하기 만합니다.

LINQ 및 WCF 데이터 서비스를 사용하여 SharePoint에 연결할 때 정확히 동일한 동작을보고 있기 때문에 LINQ/WCF 데이터 서비스가 동일한 유효하지 않은 CAML을 생성한다고 가정 할 수 있습니다.

해결 방법 (원래 LINQ/WCF 데이터 서비스를 사용한다고 가정)은 두 가지 쿼리를 수행하는 것입니다 (원래 질문에서 설명한대로). 첫 번째 LINQ 쿼리는 SharePoint에서 목록 데이터를 가져 와서 목록에 저장합니다. 두 번째 LINQ 쿼리는 원하는 데이터 만 가져 오기 위해 날짜 비교를 처리합니다.

내 특정 상황에서 SharePoint 목록에 많은 시간대가있는 항목이 많이 있지만 특정 날짜 또는 며칠 동안 항목에만 관심이 있기 때문에 다시 가져 오지 않을 방법을 찾고 싶었습니다. 첫 번째 쿼리의 전체 목록

내가 정한 것은 < = 및> = 비교를 수행하여 가까운 결과를 얻은 다음 내 두 번째 쿼리에서이를 더 제한하는 것이 었습니다. 그래서 내 두 개의 쿼리는 이제이 될 :

DateTime RightNow = DateTime.Now; 
var query = (from a in context.Alerts 
      where (a.Begins <= RightNow) && (a.Expires >= RightNow) 
      select a).ToList(); 
var query2 = from q in query 
      where q.Begins < RightNow) && (a.Expires > RightNow) 
      select q; 

첫 번째 LINQ 문은 내가 궁극적으로 관심이있는 모든 항목을 반환합니다; (그것이 datetime의 날짜 구성 요소를 비교하고 있기 때문에) 나는 그렇지 않다. 두 번째 LINQ 문을 사용하면 관심있는 내용 만 표시됩니다.

0

DateTime입니다. 오늘 어딘가에서 사용하고 있습니까? LinqPad를 사용하여 프로토 타입을 만들었고 결과를 복제 할 수있는 유일한 방법은 "where (a.Begins < DateTime.Today)"를 사용하여 쿼리를 작성한 경우였습니다.

다음은 내가 당신과 비슷한 것의 빠른 스케치입니다

void Main() 
{ 
    List<Alerts> alerts = new List<Alerts>(); 
    alerts.Add(new Alerts(DateTime.Now.AddDays(-1))); 
    alerts.Add(new Alerts(DateTime.Now)); 

    var query = from a in alerts 
       where (a.Begins < DateTime.Now) 
       select a; 
    foreach (var element in query) 
    { 
     Console.WriteLine(element.Begins); 
    } 

} 
public class Alerts 
{ 
    public DateTime Begins {get; set;} 
    public Alerts(DateTime begins) 
    { 
     Begins = begins; 
    } 
} 

내가 언급 한 바와 같이, 내가 WHERE 절에 DateTime.Today에 DateTime.Now를 변경 한 경우 귀하의 설명 결과였다 복제 할 수있는 유일한 방법 : '설명을 다시. 잘못된 DateTime 메서드를 우연히 사용하는 것에 대한 코드를 살펴볼 것입니다.

LinqPad를 사용하여 Linq 쿼리를 프로토 타이핑하는 것이 좋습니다 ... 코드를 신속하게 반복하고 문제가있는 부분을 파악할 수 있으므로 시간이 절약됩니다. 또한 인텔리 센스 및 기타 프리미엄 기능에 50 달러 상당의 가치가 있습니다.

+0

아니요. SharePoint 2010 OData 원본에 대해 쿼리하지 않을 때 잘 작동합니다. 필자가 묘사 한 동작은 SharePoint 2010 OData 원본과 비교할 때만 발생합니다. 그러나 귀하의 질문에 대답; 아니, 나는 DateTime을 사용하지 않고있다. 오늘. – RWGodfrey

+0

사실 a.Begins == DateTime.Now는 매우 이상합니다 ... 또한 "메모리에있는"레코드가있는 것처럼 들립니다. 즉, 첫 번째 쿼리에서 DateTime 절이 올바르게 작동합니다. DateTime 주변에 OData와 관련된 알려진 문제점이 있습니까? – Joe

+0

지금까지 Bing/Google/Yahoo 검색 시간과 더 많은 시행 착오 검색 시간이 없었습니다. SharePoint 2010에 대한 액세스 권한이있는 사용자가 유사한 테스트를 실행하고 결과를보고하기를 바랍니다. – RWGodfrey

1

SharePoint 2010의 OData를 사용하지 않았습니다. 그러나 SharePoint 2010 개체 모델에 대해 쿼리 할 때 게시 한 예외는 일반적인 동작입니다. 즉, 데이터를 쿼리하기 전에 쿼리를 목록으로 변환해야합니다.

var query = someSharePointQuery.ToList(); 

var results = query.Where(...).First(...); 

가 이상한 것 같다, 그러나 이것은 SP 2010 작동하는 것 같다 방법입니다

여기에 전형적인 패턴이다.셰어 데이터를 조회 할 때 사용

: -

0

SharePoint 2010 LINQ에서 올바른 CAML을 만들지 못하는 버그를 확인할 수 있습니다 (대신에 IncludeTimeValue = 'True'로 변경).)는 SharePoint Foundation 2010에 대한 2013 년 10 월 누적 업데이트로 해결됩니다. 핫픽스는 http://technet.microsoft.com/en-us/sharepoint/ff800847.aspx에서 다운로드 할 수 있습니다.

Microsoft 지원에서 알려준 SharePoint 2013에도 2013 년 12 월 누적 업데이트 (SharePoint Foundation 2013)에서 해결해야 할 동일한 버그가 있지만이를 확인할 수 없습니다. 수정 프로그램이 Office 365에도 배포되었다는 정보를 받았지만이를 확인할 수는 없습니다.

2

DateTime의 시간 요소를 포함해야하는 Linq와 SharePoint 쿼리의 경우 TimeOfDay를 사용할 수 있습니다.

var next_slots = (from s in dc.HRDates 
        where 
        s.StartTime.HasValue && 
        s.StartTime.Value.Date == appt.Value.Date && 
        s.StartTime.Value.TimeOfDay == appt.Value.TimeOfDay 
        ...