【问题标题】:How can I stop EF trying to update a computed column for SQL Server?如何阻止 EF 尝试更新 SQL Server 的计算列?
【发布时间】:2016-09-13 22:58:39
【问题描述】:

我有这个实体框架的对象映射:

public WordDefinitionMap(string schema)
{
    ToTable(schema + ".WordDefinition");
    HasKey(x => x.WordDefinitionId);

    Property(x => x.WordDefinitionId).HasColumnName(@"WordDefinitionId").IsRequired().HasColumnType("int").HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);
    Property(x => x.WordFormId).HasColumnName(@"WordFormId").IsRequired().IsUnicode(false).HasColumnType("varchar").HasMaxLength(20);
    Property(x => x.Ascii).HasColumnName(@"Ascii").IsOptional().HasColumnType("int").HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Computed);

    // Foreign keys
    HasRequired(a => a.WordForm).WithMany(b => b.WordDefinitions).HasForeignKey(c => c.WordFormId); // FK_WordDefinitionWordForm
}

public class WordDefinition
{
    public int WordDefinitionId { get; set; } // WordDefinitionId (Primary key)
    public string WordFormId { get; set; } // WordFormId (length: 20)
    public int? Ascii { get; set; } // Ascii

    // Foreign keys
    public virtual WordForm WordForm { get; set; } // FK_WordDefinitionWordForm
}

当我使用 Entity Framework 尝试更新此对象时,我收到一条异常消息:

The column "Ascii" cannot be modified because it is either a computed column or is the result of a UNION operator.

我以为我已经在指示 EF 忽略此属性,但它似乎仍在尝试更新它,即使它为空。有什么方法可以更改映射以使 EF 不设置此属性?

【问题讨论】:

  • 那么我应该在 Ascii 配置中删除以下配置 HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Computed);
  • 这不是告诉(或应该告诉)EF 不要触摸该列的指令吗?你建议我删除它,我会用什么替换它?谢谢
  • 因为 Accii 属性不是主键。 EF 会将此属性视为非生成属性。
  • 好的,但是如果我只是将其删除,那么 EF 不会将其视为普通属性并尝试将其设置为 null 吗?
  • 您在哪里创建和添加WordDefinitionMap?您确定在您的应用程序中曾经调用过 EF 的流利映射吗?

标签: c# asp.net entity-framework asp.net-web-api


【解决方案1】:

异常消息表明框架完全忽略了您的流畅配置,因为您的代码没有任何问题。

Entity Framework 然后使用标准约定映射您的属性,而不知道 Ascii 属性是计算属性。

要解决此问题,请检查您的 WordDefinitionMap 类的实例是否已创建并添加到模型构建器:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new WordDefinitionMap("mySchema"));
    //other mappings
}

顺便说一句:我建议您通过将其设置器 private 设为不可写来使您的计算属性不可写:

public int? Ascii { get; private set; } // Ascii

这将避免错误地设置此属性,而 EF 将继续从数据库中填充它而不会出现问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-25
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    相关资源
    最近更新 更多