EF Core 3.1 Fluent API无法检测到实体上的更改

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

我将EF Core 3.1与fluent API结合使用,并在如下所示的特定Map对象中配置实体:

public class CouponMap: IEntityTypeConfiguration < Coupon > {
    public void Configure(EntityTypeBuilder < Coupon > builder) {
        builder.HasKey(t = >t.Id);
        builder.Property(t = >t.Id).ValueGeneratedOnAdd();
        builder.Property(e = >e.Name).HasMaxLength(120).IsRequired();
        builder.Property(e = >e.Code).HasMaxLength(120).IsRequired();
        builder.Property(e = >e.Value).HasColumnType("decimal(19,4)").IsRequired();

        // Relations...
        builder.HasOne < AppUser > (e = >e.CreatedByUser).WithMany().HasForeignKey(e = >e.DeletedBy).IsRequired();
        builder.HasOne < AppUser > (e = >e.DeletedByUser).WithMany().HasForeignKey(e = >e.CreatedBy).IsRequired();
        builder.HasOne < AppUser > (e = >e.UpdatedByUser).WithMany().HasForeignKey(e = >e.UpdatedBy);

        // Set table name
        builder.ToTable("Coupon", "dbo");
    }
}

然后我在调试控制台上注意到,对于我的十进制字段有警告,例如:

Microsoft.EntityFrameworkCore.Model.Validation[30000] No type was specified for the decimal column 'Value' on entity type 'Coupon'. This will cause values to be silently truncated if they do not fit in the default precision and scale. Explicitly specify the SQL server column type that can accommodate all the values using 'HasColumnType()'.

但是实际上我已经在地图对象中定义了HasColumnType,如您在上面看到的。首先,我认为这可能只是一个警告,因为它无法“某种程度上”检测到更改,但是当我检查db中的表时,我看到Coupon表的Value列实际上使用默认(18,2)作为十进制精度标度( 19,4)。

优惠券对象值字段的定义如下:

public class Coupon : IHasIdColumn<int>
    {         
        public int Id { get; set; }
        public string Name { get; set; }
        .
        .
        .      
        public decimal Value { get; set; } // <== the problem guy!
        .
        .           
   }

enter image description here

此外,即使您已经在地图对象中将代码和名称字段设置为NVARCHAR(MAX),它们也被创建为HasMaxLength(120)。>

[之后,我检查了模型快照,以确保如何生成实体脚本,只是确认它忽略了我的十进制(19,4),并确认它实际上在模型快照中以如下形式创建了表脚本:

modelBuilder.Entity("MyProject.Core.DomainModels.Coupon", b = >{
    b.Property < int > ("Id").ValueGeneratedOnAdd().HasColumnType("int").HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
    .
    .
    b.Property < decimal > ("Value").HasColumnType("decimal(18,2)");
    .  
    .
    . goes with other properties
}

那到那时使我明白了,所以我尝试更新CouponMap对象中的其他属性,但未检测到这些更改。例如,我尝试将列的最大长度从120更改为500,如下所示,并添加新的迁移,但是updown函数为空。

public class CouponMap: IEntityTypeConfiguration < Coupon > {
    public void Configure(EntityTypeBuilder < Coupon > builder) {
        builder.HasKey(t = >t.Id);
        builder.Property(t = >t.Id).ValueGeneratedOnAdd();
        builder.Property(e = >e.Name).HasMaxLength(500).IsRequired(); // changed this but not detected in migration...
        builder.Property(e = >e.Code).HasMaxLength(500).IsRequired(); // also changed this but not detectedin migration...
        builder.Property(e = >e.Value).HasColumnType("decimal(19,4)").IsRequired(); // this somehow was not being detected anyways so I tried other 2 columns above

        // Relations...
        builder.HasOne < AppUser > (e = >e.CreatedByUser).WithMany().HasForeignKey(e = >e.DeletedBy).IsRequired();
        builder.HasOne < AppUser > (e = >e.DeletedByUser).WithMany().HasForeignKey(e = >e.CreatedBy).IsRequired();
        builder.HasOne < AppUser > (e = >e.UpdatedByUser).WithMany().HasForeignKey(e = >e.UpdatedBy);

        // Set table name
        builder.ToTable("Coupon", "dbo");
    }
}

我知道我可以使用System.ComponentModel.DataAnnotations.Schema来装饰我的财产,如下所示:

[Column(TypeName = "decimal(19,4)")]
public decimal Value { get; set; }

如果执行此操作并创建新的迁移,我会发现它立即检测到更改,并且我的updown函数如下所示:

 protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<decimal>(
        name: "Value",
        table: "Coupon",
        type: "decimal(19,4)",
        nullable: false,
        oldClrType: typeof(decimal),
        oldType: "decimal(18,2)");
}

protected override void Down(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<decimal>(
        name: "Value",
        table: "Coupon",
        type: "decimal(18,2)",
        nullable: false,
        oldClrType: typeof(decimal),
        oldType: "decimal(19,4)");
}

但是我想保持域对象尽可能整洁,只使用EntityMap类来定义与数据库相关的任何实体类型配置(否则使用FluentAPI的意义是什么?]

我当时以为我的实体地图对象可能没用,但是我在实体地图对象中创建的关系运行得很好。

我曾尝试清理解决方案,重建,重新启动VS,但是它们都没有起作用。有任何建议还是我在这里错过了什么?

我正在使用具有流畅API的EF Core 3.1,并在特定的Map对象中配置实体,如下所示:public class CouponMap:IEntityTypeConfiguration {public void Configure(...

c# .net-core entity-framework-core code-first ef-fluent-api
1个回答
0
投票

问题是,那些映射对象Configure函数根本没有被调用。感谢@Ivan Stoev指出我在那些映射对象中引发异常以查看它们是否会触发...

解决方案很简单:

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