我有一个带有DateTime成员的类,我将该类的实例存储到队列中(字节转换),并且我还使用Entity Framework将该实例存储到数据库中。它看起来如下:
// 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。 Works:执行转换为字符串实际上返回一个项目为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();
}
}
DB Item:
原文:2015/4/30 1:27:29 ......毫秒:841
DB项目:2015年4月30日下午1:27:29 ......毫秒:843
等于?假
答案 0 :(得分:2)
根据MSDN,日期时间值四舍五入为.000,.003或.007秒的增量。
似乎不建议将DateTime用于新工作。他们建议使用DateTime2,因为它具有更高的精度。
答案 1 :(得分:0)
我认为DateTime的格式有些不同,或者存储的数字不完全匹配。 3是有效的,因为你没有过滤任何东西。我将日期时间存储为小数,其中整数表示从1900年1月1日开始的天数,分数是日期的小数部分。 8小时是8/24 = 1/3,这是重复分数。 DateTime存储为UTC时间,并根据本地时区执行转换。我会仔细查看4中的字符串结果,并验证输入字符串和输出字符串是否完全匹配。