在不使用属性的情况下指定小数精度的最佳方法是什么。 我只需要将它设置在我的 Data.Models 中所有小数的一个位置。为每个小数点指定属性是很乏味的。
public class Customer
{
public int customerId { get; set; }
[Column(TypeName = "decimal(18,2)")]
public decimal AvailableAmount { get; set; }
}
在 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)";
}
}
对于那些在 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);
}
}
我使用 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)");
}
一切都开始正常工作。
可以使用 Precision 属性,而不是在 C# 代码中对十进制数据库类型进行硬编码。
这个:
[Column(TypeName = "decimal(18,2)")]
public decimal Quantity { get; set; }
可以这样定义:
[Precision(18, 2)]
public decimal Quantity { get; set; }
使用 EF Core 6 测试。
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/
感谢@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);
}
}