gpt4 book ai didi

c# - SQL Server 日期时间类型的默认值错误

转载 作者:太空宇宙 更新时间:2023-11-03 22:33:43 24 4
gpt4 key购买 nike

让我们假设一个 Category n-m Blog 关系:

CREATE TABLE Categories(
Id INT IDENTITY(1,1) NOT NULL,
Title NVARCHAR(MAX) NOT NULL,
Created datetime NOT NULL,
CONSTRAINT PK_Categories PRIMARY KEY(Id)
)
CREATE TABLE Posts(
Id INT IDENTITY(1,1) NOT NULL,
Subject NVARCHAR(MAX) NOT NULL,
Body NVARCHAR(MAX) NULL,
CONSTRAINT PK_Posts PRIMARY KEY (Id)
)
CREATE TABLE PostCategory(
CategoryId INT NOT NULL,
PostId INT NOT NULL,
CONSTRAINT PK_PostCategory PRIMARY KEY (CategoryId, PostId),
FOREIGN KEY ([CategoryId]) REFERENCES [Categories]([Id]),
FOREIGN KEY ([PostId]) REFERENCES [Posts]([Id])
)

搭建数据库后(参见 https://learn.microsoft.com/en-us/ef/core/get-started/aspnetcore/existing-db#reverse-engineer-your-model)我开始了我的第一个查询:

var postsWithLatestCategoryTimestamp = (
from post in db.Posts
let latestCategoryTimestamp =
(
from relation in post.PostCategory
orderby relation.Category.Created descending
select relation.Category.Created
)
.FirstOrDefault()
select new
{
post.Id, post.Subject, latestCategoryTimestamp
}
).ToList();

我得到了

System.Data.SqlClient.SqlException: 'Conversion failed when converting date and/or time from character string.'

原因:EntityFramework Core 使用了错误的默认值('0001-01-01T00:00:00.0000000'。 而不是 '1753-01-01T00:00:00.000'):

SELECT [post].[Id], [post].[Subject], COALESCE((
SELECT TOP(1) [relation.Category].[Created]
FROM [PostCategory] AS [relation]
INNER JOIN [Categories] AS [relation.Category] ON [relation].[CategoryId] = [relation.Category].[Id]
WHERE [post].[Id] = [relation].[PostId]
ORDER BY [relation.Category].[Created] DESC
), '0001-01-01T00:00:00.0000000') AS [latestCategoryTimestamp]
FROM [Posts] AS [post]

如何在不触及现有数据库的情况下修复它?


顺便说一下,OnModelCreating() 的脚手架很好:

modelBuilder.Entity<Categories>(entity =>
{
entity.Property(e => e.Created).HasColumnType("datetime");
//...
});

最佳答案

它可能看起来像 EF Core 错误,但对我来说它更像是不正确的查询。

想象一下 EF Core 以某种方式“正确”翻译了 CLR DateTime默认为 SqlServer 支持的最小日期。当您获得物化结果时,您将如何知道 latestCategoryTimestamp是默认的吗?检查 SqlServer 最小日期?如果您正在针对内存数据库或其他一些数据库运行查询怎么办?也许您会说他们必须将其转换回内存?为什么数据库最小值应该映射到 default(DateTime) ?怎么样DateTime.MinValue那么呢?

结论是没有正确映射default(DateTime) .问题是,为什么要用“神奇”的值来表示缺失值呢?数据库提供 NULL为此,C# (CLR) - 可空类型。

所以最合乎逻辑的方法是使用可空类型。您需要在查询中更改的所有内容是将强制转换添加到 DateTime?这里

select (DateTime?)relation.Category.Created

但由于您在这里只需要最大 日期,因此使用Max 就足够了。方法(但同样带有可空重载):

let latestCategoryTimestamp = post.PostCategory.Max(link => (DateTime?)link.Category.Created)

但是无论您选择哪种方法,您所需要的只是考虑 Nullable<DateTime>物化对象的属性。好的是 null无论数据库类型如何,都将指示缺少的帖子类别。

关于c# - SQL Server 日期时间类型的默认值错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56170828/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com