我有一个特殊的情况,其中表的ID定义为像这样的计算列:
CREATE TABLE [BusinessArea](
[Id] AS (isnull((CONVERT([nvarchar],[CasaId],(0))+'-')+CONVERT([nvarchar],[ConfigurationId],(0)),'-')) PERSISTED NOT NULL,
[CasaId] [int] NOT NULL,
[ConfigurationId] [int] NOT NULL,
[Code] [nvarchar](4) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_BusinessArea] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
GO
通常,当我有一个计算列时,我会这样配置它:
builder.Entity<MyEntity>()
.Property(p => p.MyComputed).HasComputedColumnSql(null);
对于.HasComputedColumnSql()
,MyComputed的值反映在实体上的插入/更新。
但是,如果计算列为PK,此技巧将无效。
关于如何使PK也能正常工作的任何想法吗?
答案 0 :(得分:2)
通过将属性BeforeSaveBehavior设置为Ignore,可以使其工作,但仅用于插入:
modelBuilder.Entity<BusinessArea>().Property(e => e.Id)
.Metadata.BeforeSaveBehavior = PropertySaveBehavior.Ignore;
但是,通常这样的设计会导致EF Core出现问题,因为它不支持可变键(主键或备用键)。这意味着它永远不会在更新后从数据库中检索Id
。您可以通过将属性标记为ValueGeneratedOnAddOrUpdate来验证这一点(这是计算列的正常行为):
modelBuilder.Entity<BusinessArea>().Property(e => e.Id)
.ValueGeneratedOnAddOrUpdate();
如果这样做,EF Core会抛出InvalidOperationException
的话
属性“ Id”不能配置为“ ValueGeneratedOnUpdate”或“ ValueGeneratedOnAddOrUpdate”,因为在将实体添加到商店后无法更改键值。