You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core中查询取值的属性无法持久化,遇无支持字段错误

解决EF Core私有计算属性映射报错问题

问题场景

我定义了如下实体类,想要让PrixTotaleTTc从关联的DetailsReceptionFournisseur数据计算得出,于是加了私有计算属性PrixTotaleTTc2,但运行时出现错误:

public class BonDeReceptionFournisseur
{
    private readonly BigSoftContext bigSoftContext;

    public BonDeReceptionFournisseur()
    {
    }

    private BonDeReceptionFournisseur(BigSoftContext bigSoftContext)
    {
        this.bigSoftContext = bigSoftContext;
    }

    [Key]
    public int Id { get; set; }
    public Decimal? PrixTotaleTTc { get; set; }

    private Decimal? PrixTotaleTTc2 => DetailsReceptions?.Sum(x => x.MontantTTc)
        ?? bigSoftContext.Set<DetailsReceptionFournisseur>()
        .Where(x => x.IdBonReception == Id).Sum(x => x.MontantTTc)
        ?? 0;
    public Decimal? PrixTotaleHt { get; set; }
    public DateTime Date { get; set; }
    public Boolean Confirmed { get; set; }
    public int FournisseurId { get; set; }
    public virtual Fournisseur Fournisseur { get; set; }
    public string GrossisteId { get; set; }

    public virtual Grossiste Grossiste { get; set; }
    public virtual ICollection<DetailsReceptionFournisseur> DetailsReceptions { get; set; }
    public FactureFournisseur FactureFournisseur { get; set; }
}

报错信息:

No backing field could be found for property 'BonDeReceptionFournisseur.PrixTotaleTTc2' and the property does not have a setter.

问题原因

EF Core会自动扫描实体类的所有属性(包括私有属性),尝试将其映射到数据库表的字段。但PrixTotaleTTc2是只读的计算属性,既没有对应的数据库字段,也没有后备字段(backing field),EF Core无法识别它的用途,因此抛出错误。

解决方案

方案1:让EF忽略该私有属性

在你的DbContext的OnModelCreating方法中,明确配置EF不要映射这个私有属性:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // 直接用属性名称字符串指定忽略的私有属性
    modelBuilder.Entity<BonDeReceptionFournisseur>()
        .Ignore("PrixTotaleTTc2");
}

这样EF就不会再尝试处理这个属性,报错自然消失。

方案2:直接改造目标属性PrixTotaleTTc

既然原本的需求就是让PrixTotaleTTc成为计算值,直接把计算逻辑移到这个公共属性上,同时用[NotMapped]标记它不需要数据库映射:

// 标记该属性不对应数据库字段
[NotMapped]
public Decimal? PrixTotaleTTc => DetailsReceptions?.Sum(x => x.MontantTTc)
    ?? bigSoftContext.Set<DetailsReceptionFournisseur>()
    .Where(x => x.IdBonReception == Id).Sum(x => x.MontantTTc)
    ?? 0;

这样就不需要额外的私有属性,直接实现需求,同时避免EF的映射问题。

方案3:使用数据库计算列(可选)

如果希望这个总和由数据库自动计算并存储,可以配置EF将PrixTotaleTTc映射为数据库计算列(需数据库支持,如SQL Server):

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<BonDeReceptionFournisseur>()
        .Property(b => b.PrixTotaleTTc)
        .HasComputedColumnSql("(SELECT COALESCE(SUM(MontantTTc), 0) FROM DetailsReceptionFournisseur WHERE IdBonReception = Id)");
}

这种方式下,属性可以保留常规的getter/setter(或者只读),EF会自动识别它是数据库计算生成的字段。

内容的提问来源于stack exchange,提问作者Houssem Nabouli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 09:30:49