我有以下类:
public class Question
{
public int QuestionId { get; set; }
...
public string QuestionUId { get; set; }
}
CREATE TABLE [dbo].[Question] (
[QuestionId] INT IDENTITY (1, 1) NOT NULL,
...
[QuestionUId] CHAR(6) DEFAULT (right(newid(),(6))) NULL,
CONSTRAINT [PK_Question] PRIMARY KEY CLUSTERED ([QuestionId] ASC)
);
CREATE UNIQUE NONCLUSTERED INDEX [Question_QuestionUId_IX]
ON [dbo].[Question]([QuestionUId] ASC);
当我插入新记录时,QuestionId 的值为零,当插入记录时,数据库的标识列会为其分配一个新值。此时 QuestionUId 为空,因此当添加记录时,它会获得 null 值,而不是我想要的默认值。
在映射中是否有某种方法可以使 QuestionUId 让数据库分配值,而不是让它为添加的新记录插入 null 值:
public QuestionMap()
{
// Primary Key
this.HasKey(t => t.QuestionId);
// Properties
this.Property(t => t.Text).HasMaxLength(4000);
// Table & Column Mappings
this.ToTable("Question");
this.Property(t => t.QuestionId).HasColumnName("QuestionId");
this.Property(t => t.QuestionUId).HasColumnName("QuestionUId");
}
这取决于。
EF 当前不支持可更新列的数据库默认值。仅当 insert 语句中未使用该列时,才应用数据库默认值,但 EF 始终发送插入语句中的所有列。避免在插入语句中发送列的唯一选择是使用数据库生成的选项(Identity
或Computed
)对其进行标记。这些将由数据库处理,您将无法在应用程序中更改它们的值。整数主键自动设置为 Identity
。
因此,如果您只想使用数据库中的默认值,并且您从未打算在应用程序中设置或更改它,您还可以使用以下命令将该列标记为Identity
:
this.Property(t => t.QuestionUId)
.HasColumnName("QuestionUId") // btw. this is not necessary because the name is same as the property
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
如果还想修改或设置应用程序中的值,则不能使用数据库生成,必须将默认值生成移动到应用程序中。永远不会使用数据库默认值。
您应该在数据库中使 QuestionUId 列不为 NULL。
按计算方式批注 QuestionUId 属性:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
这也可以在 EF 设计器中完成,假设您正在从数据库更新模型,而不是先使用代码。
更重要的是:
- 为什么需要第二个唯一标识符?
- 为什么你认为 NEWID() 的最后 6 个字符总是唯一的?
这闻起来像XYProblem:)