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

EF Core无法创建DbContext:实体类型Money未定义主键的问题求助

EF Core无法创建DbContext:实体类型Money未定义主键的问题求助

嗨,我看到你遇到EF Core创建DbContext时的主键错误了!问题出在Money这个类型上——EF Core默认会把引用类型当作需要映射到数据库表的独立实体类,但Money显然是你用来表示金额的值对象,不是需要单独建表的实体,所以EF Core找不到它的主键就报错啦。

下面给你两种常用的解决方案,都是让EF Core正确识别Money的角色:

方式一:把Money配置为值对象(推荐)

这种方式会让EF Core把Money的属性直接嵌入到ChefFoodPrice对应的数据库表中,不需要给Money单独建表。假设你的Money类大概是这样的:

public class Money
{
    public decimal Amount { get; set; }
    public string Currency { get; set; }
}

你只需要在DbContext的OnModelCreating方法里添加配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // 配置ChefFoodsPrice为值对象,拆分属性到表中
    modelBuilder.Entity<ChefFoodPrice>()
        .OwnsOne(cfp => cfp.ChefFoodsPrice, builder =>
        {
            builder.Property(m => m.Amount).HasColumnName("ChefFoodsPrice_Amount");
            builder.Property(m => m.Currency).HasColumnName("ChefFoodsPrice_Currency").HasMaxLength(3);
        });

    // 同样配置ChefFoodPriceIsDefault这个Money属性
    modelBuilder.Entity<ChefFoodPrice>()
        .OwnsOne(cfp => cfp.ChefFoodPriceIsDefault, builder =>
        {
            builder.Property(m => m.Amount).HasColumnName("DefaultPrice_Amount");
            builder.Property(m => m.Currency).HasColumnName("DefaultPrice_Currency").HasMaxLength(3);
        });

    // 顺便确认一下PriceType的关联配置
    modelBuilder.Entity<ChefFoodPrice>()
        .HasOne(cfp => cfp.PriceType)
        .WithMany() // 如果PriceType有对应的集合属性,这里替换成属性名,比如.WithMany(pt => pt.ChefFoodPrices)
        .HasForeignKey(cfp => cfp.PriceTypeId);
}

方式二:使用值转换器(HasConversion)

如果你的场景需要把Money序列化成单个数据库列(比如JSON格式),可以用值转换器来实现:

先给Money写转换逻辑:

public class MoneyConverter : ValueConverter<Money, string>
{
    public MoneyConverter() : base(
        money => JsonSerializer.Serialize(money, JsonSerializerOptions.Default),
        json => JsonSerializer.Deserialize<Money>(json, JsonSerializerOptions.Default)!)
    {
    }
}

然后在DbContext中配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<ChefFoodPrice>()
        .Property(cfp => cfp.ChefFoodsPrice)
        .HasConversion<MoneyConverter>()
        .HasColumnType("json");

    // 同样处理ChefFoodPriceIsDefault属性
    modelBuilder.Entity<ChefFoodPrice>()
        .Property(cfp => cfp.ChefFoodPriceIsDefault)
        .HasConversion<MoneyConverter>()
        .HasColumnType("json");
}

另外提个小疑问:ChefFoodPriceIsDefault这个属性从名字看像是标记是否为默认价格的布尔值,但你定义成了Money类型,是不是手误了?如果是标记默认状态,改成public bool ChefFoodPriceIsDefault { get; set; }会更合理哦。

备注:内容来源于stack exchange,提问作者maryam forex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 09:28:07