2012-02-09 1 views
1

Followind는 EF 4.2 및 LINQ를 사용하여 실행중인 문제를 설명합니다. 필자는 여러 시스템에서 이것을 시도해 보았습니다. 64 비트 및 32 바이너리 모두의 SQL (SQL Express 및 SQL 2008 R2 Sp1), VS 2010 Pro 및 Premium (디버거 포함)에서이 바이너리를 직접 실행하려고 시도했습니다 . EF와 관련된 문제이거나 내 코드 문제 일 가능성이 높고 LINQ 또는 EF와 관련된 뉘앙스가 누락 된 경우 무엇이 잘못되었는지 궁금합니다. 어떤 도움이라도 대단히 감사 할 것입니다, 6 시간 동안 그것에있어, 내 Google JuJu는 충분히 두렵습니다.LINQ Entity Framework 4.2 datetime 비교 실패

ID (Guid), 이름 (문자열) 및 시간 소인 (날짜 시간)으로 구성된 세션이라는 간단한 모델이 있습니다. dbcontext에 세션을 추가 할 수 있었고 세션 레코드가 실제로 데이터베이스에 저장되었다는 것을 디버깅에서 확인했습니다. 세션 객체를 만드는 데 사용 된 타임 스탬프는 로컬 변수에 저장되고 저장 직후 세션 객체의 새 인스턴스로 세션을 검색하려고합니다.

at System.Linq.Enumerable.First[TSource](IEnumerable`1 source) 
at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__0[TResult](IEnumerable`1 sequence) 
at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot) 
at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression) 
at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression) 
at System.Linq.Queryable.First[TSource](IQueryable`1 source) 
at efwtf.Program.Main(String[] args) in d:\vs2010\efwtf\efwtf\Program.cs:line 19 
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
at System.Threading.ThreadHelper.ThreadStart() 

내가 디버거에서 ctx.Sessions으로 드릴 결과 집합에서 볼 수 있어요 : 세션을 검색하는 코드 (LINQ)는 다음과 같은 스택 트레이스와 'System.InvalidOperationException "시퀀스에 요소가없는"'발생 내가 검색하려고하는 세션이 실제로 존재하는지, 그리고 결과 집합을 반복하고 수동으로 두 개의 타임 스탬프를 비교하면 예상대로 세션을 추출 할 수 있습니다. 코드를 실행하고 이전 실행에서 데이터베이스에 추가 된 레코드의 타임 스탬프 값을 전달하면 작동합니다. 아마도 worst case를 해결할 수있는 방법을 찾을 수 있습니다.하지만이 방법이 작동하지 않는다는 버그가 있습니다. 문제의 일부인 기능을 지원해야한다고 생각합니다. 코드는 다음과 같습니다.

using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Data.Entity; 
    using System.ComponentModel.DataAnnotations; 

    namespace efwtf 
    { 
     class Program 
     { 
      static void Main (string[] args) 
      { 
      Context ctx = new Context(); 
      DateTime ts = DateTime.UtcNow; 
      Session s1 = new Session() { Id = Guid.NewGuid(), Name = "Testing", TimeStamp = ts }; 
      ctx.Sessions.Add (s1); 
      ctx.SaveChanges(); 

      Session s2 = (from s in ctx.Sessions 
          where (s.Name == "Testing" && s.TimeStamp.Equals (ts)) 
          select s).First(); 

      Console.WriteLine (s2.Name, s2.TimeStamp); 
      } 
     } 

     class Context : DbContext 
     { 
      public DbSet<Session> Sessions { get; set; } 
     } 

     class Session 
     { 
      [Key] 
      public Guid Id { get; set; } 
      public string Name { get; set; } 
      public DateTime TimeStamp { get; set; } 
     } 
    } 

내가 s.datetime.equals (TS)를 포함하여 LINQ 문에 변화 및 datetime.compare (s.datetime, TS) == 0을 시도했지만 매번이 같은 예외가 발생합니다.

누구든지 아이디어가 있습니까? 나야? 이 코드는 내 바이너리를 크게 보이게합니까? = ^)

미리 감사드립니다.

+1

그렇다면 왜 s.TimeStamp == ts를 시도하지 않았습니까? – 000

+0

죄송합니다, 특정 예를 언급하는 것을 잊어 버렸습니다. 그러나 그것은 원래 같은 결과를 코딩 한 것입니다. – Grogh

+0

또한 똑 바른 lambda 접근'Session s2 = ctx.Sessions.First (s => s.TimeStamp == ts); – Grogh

답변

1

아래 코드를 확인하십시오! 그러나 그것이 작동하는 방식은 논리적이지 않습니다. note1 및 note2 값을 보면 날짜 값이 올바르게 저장되지만 쿼리에는 그대로 적용되지 않는다는 것을 알 수 있습니다.

var date = new DateTime(ts.Year, ts.Month, ts.Day, ts.Hour, ts.Minute, ts.Second, ts.Millisecond); 
Session s2 = (from s in ctx.Sessions 
      where (s.Name == "Testing" && s.TimeStamp == date) 
      select s).First(); 

var note1 = s2.TimeStamp == date; 
var note2 = s2.TimeStamp == ts; 

나는이 엔티티 프레임 워크가 LINQ _0 매개 변수를 @p_에 값을 할당하는 방법에 관한 몇 가지 오류가 발생 같아요. 이 쿼리는 실행되는 동안 추적되었지만 @p_ linq _0에 할당 된 값을 찾을 수 없습니다. 이 작업을 얻기 위하여

SELECT TOP (1) 
[Extent1].[Id] AS [Id], 
[Extent1].[Name] AS [Name], 
[Extent1].[TimeStamp] AS [TimeStamp] 
FROM [dbo].[Sessions] AS [Extent1] 
WHERE (N'Testing' = [Extent1].[Name]) AND ([Extent1].[TimeStamp] = @p__linq__0) 
+0

그래서 코드를 수정하고 실행하여 정상적으로 작동합니다. 다시 예외 상황으로 돌아갑니다. 테이블의 모든 레코드를 삭제하고 예외를 다시 실행했습니다. 정말로. 그것은 항상 작동해야하며, 간헐적 인 이유는 확실하지 않습니다. 아마 EF에 관한 더 많은 이슈가 있을까요? – Grogh

+0

가치가있는 부분에 대해 세션 s2 = (ctx 세션의 s에서 을 선택하십시오.) 처음(); var test1 = (sess.TimeStamp == pTimeStamp); test1이 true로 평가됩니다. #ScratchingHead – Grogh

1

, 나는 다음과 같이 타임 스탬프가 데이터베이스에 DATETIME2 데이터 형식이 될하기위한 DataColumn에 수정했습니다.

class Session 
{ 
    [Key] 
    public Guid Id { get; set; } 
    public string Name { get; set; } 

    [Column(TypeName = "datetime2")] 
    public DateTime TimeStamp { get; set; } 
} 

는 궁극적으로, 그러나 그것은 장애물 과거를 얻을 나에게 도움을 내가 다른 사람이로 실행되는 경우에 여기에 게시 할 것이라고 생각하는 일이 주위에 문제가 어떤 식 으로든 LINQ와 거짓말을 나타납니다 주어진 수 있도록이 고려 .