簡體   English   中英

DateTime LINQ相等性和實體框架未按預期工作

[英]DateTime LINQ equality and entity framework not working as expected

我有一個帶有DateTime成員的類,並將該類的實例存儲到隊列中(字節轉換),並且我也使用實體框架將該同一個實例存儲到數據庫中。 看起來如下:

// Create instance and set DateTime
MyClass m = new MyClass();
m.CurrentDT = DateTime.Now;

// Store in to database
var db = new EFContext();
db.MyClasses.Add(m);
db.SaveChanges();
db.Dispose();

// Put in to queue
myQueue.Add(m);   // stores as bytes

在某個時候,然后按如下所示將我的對象從隊列中拉出:

MyClass mQueueItem = (MyClass)NET.ByteArrayToObject(queueData);

/**
 * Converts a byte array to an object
 */
public static Object ByteArrayToObject(byte[] bytes)
{
    BinaryFormatter formatter = new BinaryFormatter();
    MemoryStream stream = new MemoryStream(bytes);
    object rval = formatter.Deserialize(stream);
    stream.Close();
    return rval;
}

1.不起作用 :然后,我嘗試在Entity Framework數據庫中找到該確切實例,但始終沒有從該搜索返回任何結果:

db.MyClasses.Where(dbItem => dbItem.CurrentDT.Equals(mQueueItem.CurrentDT));

2.不起作用 :因此,我嘗試按以下步驟手動檢查每個項目:

foreach(MyClass dbItem in db.MyClasses.ToList())
{
   Console.WriteLine("Is equal: " + dbItem.CurrentDT.Equals(mQueueItem.CurrentDT));
}

...而且我當然會為每個人弄虛作假,盡管我知道其中之一絕對是我要尋找的物品。

3.工作原理:轉換為字符串實際上會返回一項為true:

foreach(MyClass dbItem in db.MyClasses.ToList())
{
   Console.WriteLine("Is equal: " + dbItem.CurrentDT.ToString().Equals(mQueueItem.CurrentDT.ToString()));
}

4.不起作用:但是最后,運行此LINQ查詢不會再返回任何項目:

db.MyClasses.Where(dbItem => dbItem.CurrentDT.ToString().Equals(mQueueItem.CurrentDT.ToString()));

那么,關於DateTime的存儲方式以及如何在LINQ中對其運行相等性,我遺漏了什么? 為什么1或2不起作用,但是3起作用,為什么4不起作用?


編輯 :這是來自(1)的查詢

SELECT 
[Extent1].[PutInQueue] AS [PutInQueue],   // <--- This is the DateTime
[Extent1].[EmailedFrom] AS [EmailedFrom], 
[Extent1].[POName] AS [POName], 
[Extent1].[FC] AS [FC], 
[Extent1].[POSize] AS [POSize], 
[Extent1].[ExcelFilename] AS [ExcelFilename], 
[Extent1].[ExcelData] AS [ExcelData], 
[Extent1].[PDFFilename] AS [PDFFilename], 
[Extent1].[PDFData] AS [PDFData]
FROM [dbo].[IncomingPOes] AS [Extent1]
WHERE [Extent1].[PutInQueue] = @p__linq__0

這是(4)的結果查詢:

SELECT 
[Extent1].[PutInQueue] AS [PutInQueue],   // <--- This is the DateTime
[Extent1].[EmailedFrom] AS [EmailedFrom], 
[Extent1].[POName] AS [POName], 
[Extent1].[FC] AS [FC], 
[Extent1].[POSize] AS [POSize], 
[Extent1].[ExcelFilename] AS [ExcelFilename], 
[Extent1].[ExcelData] AS [ExcelData], 
[Extent1].[PDFFilename] AS [PDFFilename], 
[Extent1].[PDFData] AS [PDFData]
FROM [dbo].[IncomingPOes] AS [Extent1]
WHERE  CAST( [Extent1].[PutInQueue] AS nvarchar(max)) =  CAST( @p__linq__0 AS nvarchar(max))

編輯:完整代碼示例這是一個完整的代碼示例,用於說明問題。 將對象從EF數據庫中拉回后,DateTimes將使對象相等性失敗。

https://github.com/gnychis/DbDateTimeTest

[Serializable]
public class MyClasse
{
    [Key]
    public DateTime dateTime { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<MyClasse> MyClasses { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        // Store it in the queue
        MyClasse original = new MyClasse();
        original.dateTime = DateTime.Now;

        // Store it in the database
        var db = new MyContext();
        db.Database.ExecuteSqlCommand("TRUNCATE TABLE dbo.MyClasses");
        db.MyClasses.Add(original);
        db.SaveChanges();

        // Check the database version
        MyClasse dbItem = db.MyClasses.FirstOrDefault();
        Console.WriteLine("DB Item:");
        Console.WriteLine("  * Original: " + original.dateTime.ToString() + " ... Milliseconds: " + original.dateTime.Millisecond);
        Console.WriteLine("  * DB Item: " + dbItem.dateTime.ToString() + " ... Milliseconds: " + dbItem.dateTime.Millisecond);
        Console.WriteLine("  * Equal? " + dbItem.dateTime.Equals(original.dateTime));

        Console.ReadLine();
    }
}

數據庫項目:

  • 原文:4/30/2015 1:27:29 PM ...毫秒:841

  • DB項目:2015/4/30下午1:27:29 ...毫秒:843

  • 等於?

根據MSDN ,日期時間值四舍五入為.000,.003或.007秒。

似乎不建議將DateTime用於新工作。 相反,他們建議使用DateTime2,因為它具有更高的精度。

我認為在某些情況下DateTime的格式不同,或者存儲的數字不完全匹配。 3有效,因為您沒有過濾任何東西。 日期時間以小數形式存儲,其中整數表示從1900年1月1日開始的天數,而小數是日期的小數部分。 8小時是8/24 = 1/3,這是重復分數。 DateTime存儲為UTC時間,並根據本地時區執行轉換。 我將仔細查看4中的字符串結果,並驗證輸入字符串和輸出字符串是否完全匹配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM