实体 Framework/dbMigration - 不需要的小数舍入
Entity Framework/dbMigration - Unwanted decimal rounding
我正在研究一个新的代码优先 Entity Framework(使用 dbMigration)解决方案,我 运行 遇到了一些我无法克服的障碍.
即使我修改了生成的迁移文件以将小数字段的 precision/scale 设置为 18 和 9,当我 运行 update-database 构建数据库并调用方法时我写入种子数据,它将数据四舍五入到小数点后 2 位,而不是我预期的 9 位。在我试图播种的示例数据中,我试图将价格 属性 设置为 0.4277 但它在数据库中显示为 0.420000000
我一直在寻找这个问题的解决方案,包括为 OnModelCreating 创建一个覆盖(在我的上下文中 class),以在那里强制 precision/scale。但是当我准备好它时(请参阅下面代码中注释掉的行),虽然数据库迁移仍然按计划进行(包括按预期创建 DECIMAL(18,9)),但现在 Seed 调用没有 运行.
我希望我只是遗漏了一些小东西(而且很容易修复)。但是有人可以提供建议吗?
相关代码如下(包括初始生成的迁移代码):
public class Product
{
public int ID { get; set; }
public decimal Price { get; set; }
}
internal sealed class Configuration : DbMigrationsConfiguration<ConfiguratorContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(ConfiguratorContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
SeedData.Initialize();
}
}
public partial class Initial : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Products",
c => new
{
ID = c.Int(nullable: false, identity: true),
Price = c.Decimal(nullable: false, precision: 18, scale: 9)
})
.PrimaryKey(t => t.ID);
}
public override void Down()
{
DropTable("dbo.Products");
}
}
public class ConfiguratorContext : DbContext
{
public ConfiguratorContext() : base("name=ConfiguratorConnectionString")
{
Database.SetInitializer<ConfiguratorContext>(new CreateDatabaseIfNotExists<ConfiguratorContext>());
}
public DbSet<Product> Products { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//modelBuilder.Entity<Product>().Property(a => a.Price).HasPrecision(18, 9);
}
}
public class SeedData
{
public static void Initialize()
{
using (var context = new ConfiguratorContext())
{
if (context.Products.Any())
{
return; // DB has been seeded
}
context.Products.Add(new Product
{
Price = Convert.ToDecimal(0.4277),
});
context.SaveChanges();
}
}
}
我错过了什么?
谢谢!
- 首先,不要注释 OnModelCreating 方法的主体。这将确保数据库中价格列的精度。
- 在种子方法中设置如下值:
Price = 0.4277m
而不是 Price = Convert.ToDecimal(0.4277),
我认为您的迁移未执行,默认情况下使用 decimal(18, 2)
创建数据库。
您可以尝试使用以下初始化程序,但它不会为您创建数据库
Database.SetInitializer<ConfiguratorContext>(new MigrateDatabaseToLatestVersion<ConfiguratorContext, Configuration>());
您评论的行 modelBuilder.Entity<Product>().Property(a => a.Price).HasPrecision(18, 9);
恰到好处。
如果可以的话,我建议您远离自动迁移,并通过 Update-Database
更新数据库,以便在数据库架构更改时获得一致且可预测的结果。
我正在研究一个新的代码优先 Entity Framework(使用 dbMigration)解决方案,我 运行 遇到了一些我无法克服的障碍.
即使我修改了生成的迁移文件以将小数字段的 precision/scale 设置为 18 和 9,当我 运行 update-database 构建数据库并调用方法时我写入种子数据,它将数据四舍五入到小数点后 2 位,而不是我预期的 9 位。在我试图播种的示例数据中,我试图将价格 属性 设置为 0.4277 但它在数据库中显示为 0.420000000
我一直在寻找这个问题的解决方案,包括为 OnModelCreating 创建一个覆盖(在我的上下文中 class),以在那里强制 precision/scale。但是当我准备好它时(请参阅下面代码中注释掉的行),虽然数据库迁移仍然按计划进行(包括按预期创建 DECIMAL(18,9)),但现在 Seed 调用没有 运行.
我希望我只是遗漏了一些小东西(而且很容易修复)。但是有人可以提供建议吗?
相关代码如下(包括初始生成的迁移代码):
public class Product
{
public int ID { get; set; }
public decimal Price { get; set; }
}
internal sealed class Configuration : DbMigrationsConfiguration<ConfiguratorContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(ConfiguratorContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
SeedData.Initialize();
}
}
public partial class Initial : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Products",
c => new
{
ID = c.Int(nullable: false, identity: true),
Price = c.Decimal(nullable: false, precision: 18, scale: 9)
})
.PrimaryKey(t => t.ID);
}
public override void Down()
{
DropTable("dbo.Products");
}
}
public class ConfiguratorContext : DbContext
{
public ConfiguratorContext() : base("name=ConfiguratorConnectionString")
{
Database.SetInitializer<ConfiguratorContext>(new CreateDatabaseIfNotExists<ConfiguratorContext>());
}
public DbSet<Product> Products { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//modelBuilder.Entity<Product>().Property(a => a.Price).HasPrecision(18, 9);
}
}
public class SeedData
{
public static void Initialize()
{
using (var context = new ConfiguratorContext())
{
if (context.Products.Any())
{
return; // DB has been seeded
}
context.Products.Add(new Product
{
Price = Convert.ToDecimal(0.4277),
});
context.SaveChanges();
}
}
}
我错过了什么?
谢谢!
- 首先,不要注释 OnModelCreating 方法的主体。这将确保数据库中价格列的精度。
- 在种子方法中设置如下值:
Price = 0.4277m
而不是Price = Convert.ToDecimal(0.4277),
我认为您的迁移未执行,默认情况下使用 decimal(18, 2)
创建数据库。
您可以尝试使用以下初始化程序,但它不会为您创建数据库
Database.SetInitializer<ConfiguratorContext>(new MigrateDatabaseToLatestVersion<ConfiguratorContext, Configuration>());
您评论的行 modelBuilder.Entity<Product>().Property(a => a.Price).HasPrecision(18, 9);
恰到好处。
如果可以的话,我建议您远离自动迁移,并通过 Update-Database
更新数据库,以便在数据库架构更改时获得一致且可预测的结果。