MVC神韵---你想在哪解脱!(十四)
修正票价字段的精度
前面我们追加数据的时候遗留下来一个问题,就是在追加数据的时候,票价(Price)字段中输入的是9.99元,但是电影清单显示画面中该数据的票价字段显示为10元,这是为什么?这个问题发生的原因是因为,当EF code-first在创建数据表的时候,如果字段为Decimal类型,则使用默认的精度(18:0),从而使得9.99元被四舍五入成为10元。现在我们想要将这个默认的精度修改为(18:2),从而使得数据表中的票价字段能够存储小数点后的两位数字。可喜的是EF code-first允许你很容易地重载这个定义模型如何向数据库中存取数据的映射规则。你可以利用这个重载机制来重载EF code-first中默认的类型定义以及数据表的继承规则,然后在这个基础上进行数据的存取。为了改变我们的票价(Price)字段在数据表中的精度,打开Models文件夹下的Movie.cs文件。追加一句引用System.Data.Entity.ModelConfiguration的语句,代码如下:
using System.Data.Entity.ModelConfiguration;
并在MovieDBContext类中重载OnModelCreating方法,代码如下所示:
public class MovieDBContext : DbContext { public DbSet<Movie> Movies { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Movie>().Property(p => p.Price).HasPrecision(18, 2); } }
OnModelCreating方法可以被用来重载与定制规定我们的模型类如何与我们的数据表,进行映射的映射规则。代码中使用了EF的ModelBuilder API来定义我们的Movie对象的票价(Price)字段的精度为准确到小数点后两位。
现在完整的Movie.cs中的代码如下所示:
using System; using System.Data.Entity; using System.Data.Entity.ModelConfiguration; namespace MvcMovie.Models { public class Movie { public int ID { get; set; } public string Title { get; set; } public DateTime ReleaseDate { get; set; } public string Genre { get; set; } public decimal Price { get; set; } public string Rating { get; set; } } public class MovieDBContext : DbContext { public DbSet<Movie> Movies { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Movie>().Property(p =>p.Price).HasPrecision(18, 2); } } }
现在让我们重新运行应用程序,在浏览器中输入“http://localhost:xx/Movies”。当应用程序启动的时候,EF code-first将会再次察觉我们的模型类中的结构与数据表的结构不再匹配,然后自动重建数据表与新的模型类的结构进行匹配(具有新的票价(Price)字段的精度)。重新创建一个新的电影(Movie)数据,在票价(Price)字段中输入9.99。请注意数据表中保存后显示在电影清单画面中的该条数据的票价(Price)字段中现在也显示为9.99了,如图所示:
本节介绍了如何快速调整你的模型对象,同时在改变模型类的结构时自动将数据表中的结构保持同步。我们也介绍了如何预先在自动重建的数据表中追加默认数据,它使得你可以快速在数据表中追加一些测试数据。在下一节中,我们将介绍如何在我们的模型类中加入我们自定义的数据有效性校验规则,从而强制实现一些业务规则。
另注:4.0以后的EFramework已经不存在该精度错误。所以越来越好了,嘻嘻。