如何阻止 EF 尝试更新 SQL Server 的计算列?

问题描述 投票:0回答:2

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

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
}

当我使用实体框架尝试更新此对象时,我收到一个异常:

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

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

c# asp.net entity-framework asp.net-web-api
2个回答
6
投票

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

然后,实体框架使用标准约定映射您的属性,而不知道

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 将继续从数据库填充它而不会出现问题。


0
投票
这是为那些使用 LinqToSQL 而不是 EF 的人提供的解决方案。

在您的 dbml 中,您需要

IsDBGenerated="true"

IsReadOnly="true"
。如果你想在插入后读取该列的值,你还需要
AutoSync="OnInsert"

示例:

<Column Name="Ascii" AutoSync="OnInsert" Type="System.Int32" DbType="Int" IsReadOnly="true" IsDbGenerated="true" CanBeNull="true" />
如果您使用 dbml 设计器,请转到此列的属性菜单,然后选择“自动生成值”为 True,“自动同步”为 OnInsert,“只读”为 True(也许还可以选择“更新检查”) ' 改为从不,这是好的措施,因为您不希望更新失败,因为计算列可能返回不同的值)

© www.soinside.com 2019 - 2024. All rights reserved.