在EF的早期版本中,要指定计算列,我们将编写:
modelBuilder
.Entity<Type>()
.Property(x => x.ComuptedProperty)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
这是有道理的,因为计算列的SQL表达式在数据库中写入一次。
但是,在迁移到EF Core后,我们意识到语法应该改为:
modelBuilder
.Entity<Type>()
.Property(x => x.ComuptedProperty)
.HasComputedColumnSql("SQL Expression should be duplicated here");
当我们首先进行代码时,这是有道理的。因为EF Core在创建表时使用此SQL表达式。
然而,对于DB第一种情况,这根本没有意义。我们试图将此参数留空,并引发异常抱怨:
字符串参数&#39; sql&#39;不能为空
现在,当你想拥有一个数据访问生成器时情况变得更糟。我们怎么能忽略这个参数?
答案 0 :(得分:2)
确实在使用HasComputedColumnSql
时,必须指定在为关联表生成SQL脚本时将用于计算列的SQL查询。就像你说的,这仅对Code First方法有用。
在Database First方法中,您可以使用以下方法之一frol PropertyBuilder<TProperty>
类型(描述来自这些方法的XML文档):
ValueGeneratedOnAdd()
:将属性配置为仅在保存新实体时生成值,除非设置了非空的非临时值,在这种情况下将保存设置值。该值可以由客户端值生成器生成,也可以由数据库生成,作为保存实体的一部分。ValueGeneratedOnAddOrUpdate()
:配置属性以在保存新实体或现有实体时生成值。ValueGeneratedOnUpdate()
:配置属性以在保存现有实体时生成值。在您的情况下,因为它是一个计算列,那么在添加和保存数据时可能会生成该值,因此您必须使用ValueGeneratedOnAddOrUpdate()
方法。 EF文档再次说:
这只是让EF知道为添加或更新的实体生成的值,它不能保证EF会设置生成值的实际机制。