不需要的十进制截断

Gra*_*avy 26 c# asp.net-mvc entity-framework truncate

我的型号:

public class Product
{
    ...
        public decimal Fineness { get; set; }
    ...
}
Run Code Online (Sandbox Code Playgroud)

播种数据库:

new List<Product>
        {
            new Product { ..., Fineness = 0.757M, ... },
            new Product { ..., Fineness = 0.674M, ... },
            new Product { ..., Fineness = 0.475M, ... }
        }.ForEach(p => context.Products.Add(p));
Run Code Online (Sandbox Code Playgroud)

查询数据库以测试种子:

var products = db.Products.ToList();
foreach (var p in products)
{
    S.D.Debug.WriteLine("ProductList: {0}, {1}", p.Name, p.Fineness);
}
Run Code Online (Sandbox Code Playgroud)

控制台输出:

ProductList: Test Product, 0.75 
ProductList: Test Product, 0.67 
ProductList: Test Product, 0.47    
Run Code Online (Sandbox Code Playgroud)

我做的事真的很傻或者什么?一切都被截断到2位小数.

解决方案 - 感谢Patrick:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Product>().Property(x => x.Fineness).HasPrecision(10, 5);
}
Run Code Online (Sandbox Code Playgroud)

Pat*_*gee 22

因此,您已定义了标准实体模型,这里是带有id和decimal的产品,以及您需要的任何其他内容等.

public class Product
{
    public int Id { get; set; }
    public decimal Fineness { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

所以我已经定义了一个initlizer,在这种情况下,数据库将丢弃并重新创建我提供的任何种子信息,每次运行和执行我的应用程序时,都会调用它.

public class Initializer : DropCreateDatabaseAlways<Context>
{
    protected override void Seed(Context context)
    { 
        // note how I am specifying it here as 4 digits after the decimal point
        // and for the second one, 3 digits
        // this is where EF precision must be configured so you can expect
        // the values you tell EF to save to the db
        context.Products.Add(new Product() {Id = 1, Fineness = 145.2442m});
        context.Products.Add(new Product() {Id = 2, Fineness = 12.341m});
    }
}

public class Context : DbContext
{
    public IDbSet<Product> Products { get; set; }

    public Context()
    {
        // I always explicitly define how my EF should run, but this is not needed for the answer I am providing you
        Configuration.AutoDetectChangesEnabled = true;
        Configuration.ProxyCreationEnabled = true;
        Configuration.LazyLoadingEnabled = true;
        Configuration.ValidateOnSaveEnabled = true;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // so here, I am override the model configuration which is what 
        // EF can use in order to set-up the behaviour of how everything 
        // is configured in the database, from associations between
        // multiple entities and property validation, Null-able, Precision, required fields etc
        modelBuilder.Configurations.Add(new ProductConfiguration());
    }
}

public class ProductConfiguration : EntityTypeConfiguration<Product>
{
    public ProductConfiguration()
    {
        ToTable("Product");
        HasKey(x => x.Id).Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        // HAS PRECISION. 
        // Enforces how the value is to be stored in the database
        // Here you can see I set a scale of 3, that's 3 digits after
        // the decimal. Notice how in my seed method, I gave a product 4 digits!
        // That means it will NOT save the product with the other trailing digits.
        Property(x => x.Fineness).HasPrecision(precision: 10, scale: 3);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用SQL Server对象资源管理器,我可以查看我的localdb示例产品,以了解EF如何配置我的数据库.

在此输入图像描述

[TestFixture]
public class Tests
{
    [Test]
    public void Test()
    {
        Database.SetInitializer(new Initializer());

        using (var ctx = new Context())
        {
            // assert our findings that it is indeed not what we actually specified in the seed method, because of our Entity configuration with HasPrecision.
            Product product1 = ctx.Products.Find(1);
            Assert.AreEqual(145.244m, product1.Fineness);

            Product product2 = ctx.Products.Find(2);
            Assert.AreEqual(12.341m, product2.Fineness);
        }         
    }
}
Run Code Online (Sandbox Code Playgroud)

单元测试运行,播种数据库,我们断言了我们的假设

所以我们需要确保数据库知道它应该如何存储我们的十进制值,通过使用实体框架的模型构建器配置来配置我们的实体,通过使用FluentApi,我们可以通过设置属性特征EntityTypeConfiguration<T>.

  • 这是一个惊人的解释.然而,只需在映射属性中添加以下内容(就在LINQ查询之后)就帮助解决了我非常相似的问题:`.HasPrecision(precision:10,scale:3);` (6认同)