2012-02-09 2 views
1

Последовательность описывает проблему, с которой я сталкиваюсь с использованием EF 4.2 и LINQ. Я пробовал это на нескольких системах и несколько вариантов SQL (SQL Express и SQL 2008 R2 Sp1), VS 2010 Pro и Premium, как в 64-битных, так и в 32 двоичных файлах, как с отладчиком, так и при попытке запустить двоичный файл напрямую , Мне интересно, на что я наткнулся, если это проблема с EF или, скорее, проблема с моим кодом, и мне не хватает некоторых нюансов, связанных с LINQ или EF. Любая помощь была бы очень признательна, если бы на ней в течение 6 часов, мой Google JuJu недостаточно силен, я боюсь.LINQ Entity Framework 4.2 сравнение даты и времени

У меня есть простая модель с именем session, состоящая из ID (Guid), Name (String) и Timestamp (DateTime). Я могу добавить сеанс в dbcontext и проверил при отладке, что запись сеанса действительно хранится в базе данных. Временная метка, используемая для создания объекта сеанса, хранится в локальной переменной, и сразу после сохранения я пытаюсь извлечь сеанс в новый экземпляр объекта сеанса. Код, который извлекает сеанс связи (LINQ) бросает «System.InvalidOperationException„Последовательность не содержит элементов“» со следующим StackTrace:

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 в отладчик и посмотреть в результирующем что сеанс, который я пытаюсь восстановить, действительно существует, и если я перебираю результат и вручную сравниваю две метки времени, я могу извлечь сеанс, как ожидалось. Если я запустил код и передал значение временной метки для записи, которая была добавлена ​​в базу данных в предыдущем запуске, она работает. Я могу найти работу вокруг, в худшем случае, изменить тип данных на строку, возможно, но мне кажется, что это не работает, я предполагаю, что может быть частью проблемы, что функциональность должна поддерживаться. Далее следует код.

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; } 
     } 
    } 

Я пробовал вариации на заявление LINQ, включая s.datetime.equals (TS) и datetime.compare (s.datetime, Т.С.) == 0, но каждый раз, когда он бросает то же исключение.

У кого-нибудь есть идеи? Это я? Этот код делает мой бинарный вид большим? = ^)

Заранее спасибо

+1

Итак, почему вы не пробовали s.TimeStamp == ts? – 000

+0

Извините, забыли упомянуть этот конкретный пример, но это то, что я изначально закодировал, те же результаты. – Grogh

+0

также испробовал прямой лямбда-подход '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; 

Я предполагаю, что это какая-то ошибка, связанная с тем, как Entity Framework присваивает значение @p_ LinQ _0 параметр. Это запрос, который я проследил, выполняется, но я не смог найти, что назначено для @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 = (от s в ctx.Sessions выберите s) .First(); var test1 = (sess.TimeStamp == pTimeStamp); test1 оценивает значение true. #ScratchingHead – Grogh

1

Для того, чтобы получить эту работу, я изменил DataColumn для TimeStamp быть тип данных Datetime2 в базе данных следующим образом.

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

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

В конечном счете считают, что это работа вокруг, учитывая, что этот вопрос, как представляется, лежит с LINQ в некотором роде, однако это помогло мне пройти препятствие и думал, что пост здесь, в случае, если кто-то работает в этом ,

Смежные вопросы