验证 30000 没有为小数列指定类型

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

在不使用属性的情况下指定小数精度的最佳方法是什么。 我只需要将它设置在我的 Data.Models 中所有小数的一个位置。为每个小数点指定属性是很乏味的。

public class Customer
{
    public int customerId { get; set; }

    [Column(TypeName = "decimal(18,2)")]
    public decimal AvailableAmount { get; set; }
}
c# entity-framework ef-core-2.0
6个回答
16
投票

在 dbcontext 中的

OnModelCreating
方法中添加以下内容:

protected override void OnModelCreating(ModelBuilder builder)
{         
   foreach (var property in builder.Model.GetEntityTypes()
                .SelectMany(t => t.GetProperties())
                .Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?)))
            {   
              property.Relational().ColumnType = "decimal(18,2)";   
            }
}

10
投票

对于那些在 EntityFrameworkCore 6.0 上遇到同样问题的人来说,这样做就可以了:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var decimalProps = modelBuilder.Model
    .GetEntityTypes()
    .SelectMany(t => t.GetProperties())
    .Where(p => (System.Nullable.GetUnderlyingType(p.ClrType) ?? p.ClrType) == typeof(decimal));

    foreach (var property in decimalProps)
    {
        property.SetPrecision(18);
        property.SetScale(2);
    }
}

9
投票

我使用 ASP.NET CORE 5 遇到过这个问题。我将以下代码添加到 DbContext 中的 OnModelcreating 方法中。

protected override void OnModelCreating(ModelBuilder modelBuilder)// Crée la migration
    {
        modelBuilder.Entity<MyEntity>().Property(p => p.Prix).HasColumnType("decimal(18,4)");

    }

一切都开始正常工作。


6
投票

可以使用 Precision 属性,而不是在 C# 代码中对十进制数据库类型进行硬编码。

这个:

[Column(TypeName = "decimal(18,2)")]
public decimal Quantity { get; set; }

可以这样定义:

[Precision(18, 2)]
public decimal Quantity { get; set; }

使用 EF Core 6 测试。


0
投票
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
   var properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(decimal));
    foreach (var property in properties)
    {
       modelBuilder.Entity(entityType.Name).Property(property.Name).HasColumnType("decimal(18,2)");
    }
}

http://jameschambers.com/2019/06/No-Type-Was-Specified-for-the-Decimal-Column/


0
投票

感谢@Bigabdoul 的回答。有些情况被忽略了

例如,如果您为特殊字段添加了特殊注释,则此代码不关心并覆盖它。 但是我已经更改了如下代码以不修改该字段。

也许您将这些代码之一用于特殊属性:

1- 使用 Column(TypeName)

[Column(TypeName = "decimal(18,2)")]
public decimal Quantity { get; set; }

2-使用Precision

[Precision(18, 2)]
public decimal Quantity { get; set; }

3- 使用 PropertyBuilder.HasPrecision 方法

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyEntity>().Property(p => p.MyProperty).HasPrecision(18, 2);
}

4- 使用 PropertyBuilder.HasColumnType 方法

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyEntity>().Property(p => p.MyProperty).HasColumnType("decimal(18,2)");
}

5-使用IEntityTypeConfiguration接口

public class MyEntityConfiguration : IEntityTypeConfiguration<MyEntity>
{
    public void Configure(EntityTypeBuilder<MyEntity> builder)
    {
        builder.ToTable("MyEntity");
        builder.Property(x => x.MyEntity).HasPrecision(18, 2);
    }
}

然后

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly);
    // Or use explicitly
    //modelBuilder.ApplyConfiguration(new MyEntityConfiguration());
}

所有这些情况都将被忽略。

但是这段代码关心它们并检查是否没有相关的注释,它会将它添加到属性中。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var decimalProps = modelBuilder.Model
        .GetEntityTypes()
        .SelectMany(t => t.GetProperties())
        .Where(p => (System.Nullable.GetUnderlyingType(p.ClrType) ?? p.ClrType) == typeof(decimal));

    foreach (var property in decimalProps)
    {
        var annotations = property.GetAnnotations();
        if (annotations.Count(x => x.Name is "Relational:ColumnType" or "Precision" or "Scale") != 0) continue;
        // Or Use this line if you use older version of C#
        // if (annotations.Count(x => x.Name == "Relational:ColumnType" || x.Name == "Precision" || x.Name == "Scale") != 0) continue;
        property.SetPrecision(18);
        property.SetScale(2);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.