c# - 在主键中创建带有 DateTime 的实体

标签 c# sql-server entity-framework-5

假设我们在 SQL Server 中有“EfTest”数据库和下表:

create table Test
(
    Id INT NOT NULL IDENTITY(1,1),
    TS DATETIME NOT NULL
    PRIMARY KEY (TS, Id)
)

我们想用 EF(在我的例子中是 EF 5)添加东西。我们在示例项目中从数据库创建 edmx 文件并编写以下代码:

    static void Main(string[] args)
    {
        var ctx = new EFTestEntities();

        var t = new Test();
        t.TS = DateTime.Now;

        ctx.Tests.Add(t);

        ctx.SaveChanges();
    }

我们运行它,它在 ctx.SaveChanges() 行上出现 DbUpdateConcurrencyException 失败,说:

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

显然,那里没有发生并发。 SQL Server 事件探查器报告以下查询由 EF 运行:

exec sp_executesql N'insert [dbo].[Test]([TS])
values (@0)
select [Id]
from [dbo].[Test]
where @@ROWCOUNT > 0 and [Id] = scope_identity() and [TS] = @0',N'@0 datetime2(7)',@0='2015-08-27 18:29:45.1025442'

问题出在这里:@0 datetime2(7),@0='2015-08-27 18:29:45.1025442'DATETIME2DATETIME 精度更高,TS 检查 WHERE 子句可防止它找到刚刚插入的行.

问题:抛开我将 DATETIME 列作为 PK 的一部分的原因,我如何让 EF 插入行而不抛出异常?

我可以将 TS 列设为 DATETIME2 类型,这样可以解决问题,但我不想浪费数据库空间,因为一些 EF 问题。 我仔细检查了一下,似乎都是 DATETIMEDATETIME2占用 8 个字节,所以我想我是这样走的。

我可以在文本编辑器中编辑 .edmx 文件,让它认为主键只是 Id 列(所以 EF 不会使用 TS 以在插入后查找 Id),但 VS 将在我下次从数据库更新实体时覆盖我的编辑。

还有其他选择吗?

最佳答案

我最终使用 DATETIME2 作为列类型,因为没有空间权衡:DATETIMEDATETIME2 都占用 8 个字节。

关于c# - 在主键中创建带有 DateTime 的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32262107/

相关文章:

c# - Moon APNS 的未知错误 P12 文件

c# - ObservableCollection 中索引在范围内的不合逻辑 ArgumentOutOfRangeException

sql-server - 递归选择

c# - 使用 LINQ 列出(和返回)的列

c# - 在可重启模式下以编程方式在多个 block 中并行下载文件

c# - 使用字符串通过 DbContext 访问表

sql-server - 如何自动刷新SQL Server Management Studio智能感知缓存?

sql-server - SQL Server 全文索引包含搜索完全匹配包含 "it"

ef-code-first - EF5 代码首先排序嵌套项

c# - 在 Entity Framework 中将 1 映射到 0-1