我是否可以告诉EF6如果它为空且没有默认值,则不尝试将值插入列中?

时间:2014-01-01 10:52:00

标签: sql-server entity-framework entity-framework-6

我有以下课程:

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,因此当添加记录时,它获取的值为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");
}

2 个答案:

答案 0 :(得分:1)

这取决于。

EF目前不支持可更新列的数据库默认值。仅当insert语句中未使用该列时才应用数据库缺省值,但EF始终会在insert语句中发送所有列。避免在insert语句中发送列的唯一选择是使用数据库生成选项(IdentityComputed)对其进行标记。这些将由数据库处理,您将无法在应用程序中更改其值。整数主键自动设置为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);

如果要在应用程序中修改或设置值,则无法使用数据库生成,必须将默认值生成移动到应用程序。永远不会使用数据库默认值。

答案 1 :(得分:0)

您应该在数据库中使QuestionUId列为NOT NULL。

将QuestionUId属性注释为computed:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]

这也可以在EF设计器中完成,假设您要从数据库更新模型而不是首先使用代码。

更重要的是:

  1. 为什么需要第二个唯一标识符?
  2. 为什么你认为NEWID()的最后6个字符总是唯一的?
  3. 这闻起来像XYProblem:)