我有一个如下所示的数据库表:
CREATE TABLE [dbo].[Configurations]
(
[ConfigurationId] dbo.InternalRecordId NOT NULL PRIMARY KEY DEFAULT 1,
[EnableAuditLogging] BIT NOT NULL
)
请注意,主键的类型是用户定义的类型(UDT):
CREATE TYPE [dbo].[InternalRecordId]
FROM int NOT NULL
此表中的记录映射到普通数据类型对象:
public class Configuration
{
public int Id { get; set; }
public bool EnableAuditLogging { get; set; }
}
我已将实体框架配置为将Id
属性映射到ConfigurationId
列作为非标识主键。我已经使用调试器来验证这个映射代码是否实际运行。
class ConfigurationMap : EntityTypeConfiguration<Entities.Configuration>
{
public ConfigurationMap()
{
HasKey(t => t.Id);
Property(t => t.Id)
.HasColumnName("ConfigurationId")
.HasDatabaseGeneratedOption(null);
}
}
当我使用Entity Framework将记录插入表中时,如下所示:
var database = new LocalDbContext();
var configuration = new Configuration
{
Id = 1,
};
database.Configurations.Add(configuration);
database.SaveChanges();
然后对SaveChanges
的调用抛出一个OptimisticConcurrencyException
,建议在插入后没有找到该记录。
我使用SQL Server Profiler来检查它在做什么:
INSERT [dbo].[Configurations]([EnableAuditLogging])
VALUES (@0)
SELECT [ConfigurationId]
FROM [dbo].[Configurations]
WHERE @@ROWCOUNT > 0 AND [ConfigurationId] = scope_identity()
我注意到它没有在ConfigurationId
语句中指定INSERT
的值,并且它也尝试从scope_identity
获取值,即使它不是IDENTITY
列。
当我将列的类型更改为int
而不是UDT时,问题不再出现。
答案 0 :(得分:0)
问题与这一行有关:
HasDatabaseGeneratedOption(null);
此方法的文档说明:
设置'null'将从属性中删除数据库生成的模式构面。设置'null'将导致与指定'None'相同的运行时行为。
尽管有第二句话,我还是尝试将其更改为:
HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
这解决了这个问题。因此,将其设置为null
似乎不执行与指定DatabaseGeneratedOption.None
相同的操作。