我正在试验这种代码优先的方法,但我现在发现类型System的属性。Decimal被映射到Decimal(18,0)类型的sql列。
如何设置数据库列的精度?
我正在试验这种代码优先的方法,但我现在发现类型System的属性。Decimal被映射到Decimal(18,0)类型的sql列。
如何设置数据库列的精度?
当前回答
使用
System.ComponentModel.DataAnnotations;
你可以简单地把这个属性放在你的模型中:
[DataType("decimal(18,5)")]
其他回答
显然,你可以重写DbContext.OnModelCreating()方法,并像这样配置精度:
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().Property(product => product.Price).Precision = 10;
modelBuilder.Entity<Product>().Property(product => product.Price).Scale = 2;
}
但当你必须处理所有与价格相关的属性时,这是相当乏味的代码,所以我想到了这个:
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
var properties = new[]
{
modelBuilder.Entity<Product>().Property(product => product.Price),
modelBuilder.Entity<Order>().Property(order => order.OrderTotal),
modelBuilder.Entity<OrderDetail>().Property(detail => detail.Total),
modelBuilder.Entity<Option>().Property(option => option.Price)
};
properties.ToList().ForEach(property =>
{
property.Precision = 10;
property.Scale = 2;
});
base.OnModelCreating(modelBuilder);
}
在重写方法时调用基方法是一种良好的实践,即使基实现什么也不做。
更新:这篇文章也很有帮助。
在EF6
modelBuilder.Properties()
.Where(x => x.GetCustomAttributes(false).OfType<DecimalPrecisionAttribute>().Any())
.Configure(c => {
var attr = (DecimalPrecisionAttribute)c.ClrPropertyInfo.GetCustomAttributes(typeof (DecimalPrecisionAttribute), true).FirstOrDefault();
c.HasPrecision(attr.Precision, attr.Scale);
});
你总是可以告诉EF在OnModelCreating函数中的Context类中使用约定来做到这一点,如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// <... other configurations ...>
// modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
// modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
// modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
// Configure Decimal to always have a precision of 18 and a scale of 4
modelBuilder.Conventions.Remove<DecimalPropertyConvention>();
modelBuilder.Conventions.Add(new DecimalPropertyConvention(18, 4));
base.OnModelCreating(modelBuilder);
}
这只适用于Code First EF fyi,并适用于映射到db的所有十进制类型。
Dave Van den Eynde给出的答案现在已经过时了。有2个重要的变化,从EF 4.1开始,ModelBuilder类现在是DbModelBuilder,现在有一个DecimalPropertyConfiguration。HasPrecision方法,其签名为:
public DecimalPropertyConfiguration HasPrecision(
byte precision,
byte scale )
其中精度是db将存储的数字总数,而不管小数点落在哪里,scale是它将存储的小数位数。
因此,不需要像所示那样遍历属性,只需要从属性调用即可
public class EFDbContext : DbContext
{
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Class>().Property(object => object.property).HasPrecision(12, 10);
base.OnModelCreating(modelBuilder);
}
}
[Column(TypeName = "decimal(18,2)")]
这将与EF Core代码首次迁移一起工作,如下所述。