2016-06-02 3 views
3

Linq2DB로 작업하는 동안 불쾌한 문제가 발생했습니다. 비교 연산자 ==>=이 올바르게 작동하지 않습니다. 운영자 <=이 정상적으로 작동하지만. 처음에는 문제가 Linq To SQLite에 있다고 결론을 내었으므로 github에 문제가 발생했습니다. 그런데 LinqToSql에서 같은 문제가 발견되었습니다.IQueryable. 비교 연산자 (== 및> =)의 특성

클래스 :

[Table(Name = "Records")] 
    public class Record 
    { 
     [Column(Name = "Date"), NotNull] 
     public DateTime Date { get; set; } 

     [Column(Name = "Value"), NotNull] 
     public decimal Value { get; set; } 

     public override string ToString() 
     { 
      return string.Format("{0} - {1}", Date, Value); 
     } 
    } 

    public class Db : LinqToDB.Data.DataConnection 
    { 
     public Db() : base("MyDatabase") { } 

     public ITable<Record> Records { get { return GetTable<Record>(); } } 
    } 

테스트 쿼리 나는 문제를 보여주기 위해 거기에서 코드를 반복 할 수 있습니다

var date = DateTime.ParseExact("14.01.2016", "dd.MM.yyyy", null); 
    Console.WriteLine("All:"); 
    using (var db = new Db()) 
    { 
     db.Records 
      .ToList() 
      .ForEach(Console.WriteLine); 
    } 
    Console.WriteLine("With Date >= {0}", date); 
    using (var db = new Db()) 
    { 
     db.Records 
      .Where(x => x.Date >= date) 
      .ToList() 
      .ForEach(Console.WriteLine); 
    } 

인쇄 : IEnumerable을 해결할 수있는 문제에

All: 
01.01.2016 0:00:00 - 67 
02.01.2016 0:00:00 - 75 
03.01.2016 0:00:00 - 70 
04.01.2016 0:00:00 - 81 
07.01.2016 0:00:00 - 8 
08.01.2016 0:00:00 - 27 
11.01.2016 0:00:00 - 30 
12.01.2016 0:00:00 - 68 
13.01.2016 0:00:00 - 20 
14.01.2016 0:00:00 - 34 
15.01.2016 0:00:00 - 1 
16.01.2016 0:00:00 - 66 
With Date >= 14.01.2016 0:00:00 
15.01.2016 0:00:00 - 1 
16.01.2016 0:00:00 - 66 

비교 문제 :

Console.WriteLine("With Date >= {0}", date); 
    using (var db = new Db()) 
    { 
     db.Records 
      .ToArray() 
      .Where(x => x.Date >= date) 
      .ToList() 
      .ForEach(Console.WriteLine); 
    } 

인쇄 :

... 
With Date >= 14.01.2016 0:00:00 
14.01.2016 0:00:00 - 34 
15.01.2016 0:00:00 - 1 
16.01.2016 0:00:00 - 66 

그래서 질문은 다음과 같은 행동의 이유는 무엇인가?

편집 : 문제가 시간 차이가있는 경우

는 왜 SQLite는 관리자의 비교는 정확합니까?

enter image description here

+3

db가 mach와 다른 시간대를 사용하고 있습니까? 그것 qquerying? – Servy

+0

@Servy, 고맙습니다. 그것을 어떻게 확인할 수 있습니까? –

+0

현재 시간을 가져와 시계와 비교할 수있는 쿼리를 작성할 수 있습니다. – Servy

답변

2

짧은 대답과 긴 대답이 있습니다. 지적했듯이, DB는 다른 시간대를 사용하고 있습니다. 이것은 다소 SQLite 특정, SQLite의 시간대는 UTC로 설정됩니다.

var dt = new System.DateTime(2016,7,30).AddHours(-9.0).ToLocalTime(); 
dt.Dump(); 
Table2 
    .Where(r => r.Date1 == dt).Dump(); 

당신은 다시 얻을 것이다 : 그래서, 간단한 해결책이 라인을 따라 뭔가있을
100 2016-07-30 (100 단지 ID입니다). 그래서 평등은 의도 한대로 작동합니다. 날짜는 yyyy-MM-dd입니다. 실제로 운이 좋다면
var dt= new DateTime(2016, 7, 30,0,0,0,DateTimeKind.Local);
또는 DateTimeKind.UTC으로 얻을 수 있습니다.

당신은 (...이 BTW LinqPad에서 한 라이너) 결과를 볼이 두 개의 서로 다른 날짜를 시도하고 있습니다

:

using (var db = new Db()) 
      { 
       Record newdt = new Record { Value = 1000, Date = new System.DateTime(2016, 8, 30, 0, 0, 0, DateTimeKind.Local) }; 
       Record newdtUtc = new Record { Value = 2000, Date = new System.DateTime(2016, 8, 30, 0, 0, 0, DateTimeKind.Utc) }; 
       db.Insert(newdt); 
       db.Insert(newdtUtc); 

을 그래서 지금 우리가 년 8 월 (30)를 현지에와있는 UTC에서 DB. 이제 그들을 추출해 보겠습니다 :

var dateLoc = new DateTime(2016, 8,30 ,0,0,0,DateTimeKind.Local); 
    var dateUTC = new DateTime(2016, 8, 30, 0, 0, 0, DateTimeKind.Utc); 
    var date = dateLoc.ToString() + " Or " + dateUTC.ToString(); 
    Console.WriteLine("With Date == {0}", date); 

    using (var db = new Db()) 
    { 
     db.Records 
      .Where(x => x.Date == dateLoc || x.Date == dateUTC) 
      .ToList() 
      .ForEach(Console.WriteLine); 
    } 

그리고 그 (plz.ToString은()) 0시 0분 0초와 UTC와 현지을 모두 반환

ConsoleApplication1.exe

이제 더 이상 답 :

SQLite는의 시간대는 UTC에 작은 문제가되는 설정되어 있다는 사실. 더 큰 것은 SQLite가 실제로 Datetime의 개념을 가지고 있지 않다는 것입니다. 날짜를 텍스트 또는 부동 소수점으로 저장하며 원하는 유형을 데이터 열에 지정할 수 있습니다. 그리고 실제로 SQLite는 날짜 변환 함수를 내부에 포함하고 있습니다. 의심 할 여지없이 SQLiteManager가 후드에서 앞뒤로 변환됩니다. 따라서 날짜를로드하는 데 사용하는 항목과 날짜를 추출하는 데 사용하는 항목에 따라 구현 된 변환의 종류에 따라 결과가 달라질 수 있습니다. 실제로 LinqToDB는 자동으로 LinqToSql 이외의 다른 작업을 수행하지 않습니다. 알 수없는 날짜 형식에 대해 불평하면 극적으로 실패 할 것입니다.

위의 조정으로도 날짜를 일치시킬 수 없으므로 로케일을 조사해야합니다. 짧은 시간 날짜를 YYYY-MM-DD로 설정하고 긴 시간 형식을 HH : MM : SS로 설정 한 다음 날짜를로드하고 압축을 풀어 일치하는 항목이 있는지 확인하십시오. 하나는 SQLite에서 부동 소수점 또는 텍스트로 날짜를 저장합니다.

2

데이터베이스는 사용자의 시스템에서 수행 할 때보다 데이터베이스에서 수행 할 때 계산이 다른 이유는 로컬 컴퓨터, 이외의 다른 시간대로 설정되어 있습니다.

+1

감사합니다. 더 자세히 알 수있는 곳은 무엇입니까? 결국 현재 날짜와 비교되는 날짜가 달라 지든 상관 없습니까? –

+1

과 SQLite Manager의 비교가 정확한 이유는 무엇입니까 –

+0

@FoggyFinder Google을 사용하여 시간대가 무엇인지 자세히 알아볼 수 있습니다. 주제에 관해 많은 자료가 있습니다 .SQLite Manager는 데이터베이스의 시간대에 날짜가 있어야한다고 생각합니다. – Servy