Entity Framework 7 为模型构建器设置小数精度

Entity Framework 7 Set decimal precision for model builder

我一直在尝试弄清楚如何为 EF7 (Beta 4) 设置小数精度,但没有成功。

我期待做这样的事情:

modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).Precision(10, 6)

这似乎不可用,但我能够在 GitHub 的存储库中找到以下 class:

https://github.com/aspnet/EntityFramework/blob/7.0.0-beta4/src/EntityFramework.Relational/RelationalDecimalTypeMapping.cs

没有使用 RelationalTypeMapping classes 或方法签名的示例。也许这只是用作检索信息的映射 api 的一部分?

我可能认为这是另一个地方如下:

modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).ForRelational().ColumnType() 

modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).ForSqlServer().ColumnType()

这些只需要一个字符串,是这个功能还没有实现,还是我没有找对地方?

编辑: 刚刚意识到字符串可能适用于 .ColumnType("decimal(10,6)") 类型的解决方案,直到进一步构建,仍然不介意得到一些澄清一下,因为我不想为此使用字符串

编辑: 在 bricelam 澄清后,我最终创建了以下扩展,暂时使用以避免使用字符串,我很欣赏他们方法的简单性:

public static RelationalPropertyBuilder DecimalPrecision(this RelationalPropertyBuilder propertyBuilder, int precision, int scale)
    {
        return propertyBuilder.ColumnType($"decimal({precision},{scale})");
    }

用法示例:

modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).ForRelational().DecimalPrecision(10,6);

编辑: 对 RC1 进行修改

我还没有对这些进行测试,但我只是将以下 2 个示例放在一起,看看 RC1 可能是什么样子

    public static PropertyBuilder DecimalPrecision(this PropertyBuilder propertyBuilder, string precision, string scale)
    {
        return propertyBuilder.HasColumnType($"decimal({precision},{scale})");
    }

    public static PropertyBuilder SqlDecimalPrecision(this PropertyBuilder propertyBuilder, string precision, string scale)
    {
        return propertyBuilder.ForSqlServerHasColumnType($"decimal({precision},{scale})");
    }

因为我还没有尝试过这个,所以我不确定 "HasColumnType" 或 "ForSqlServerHasColumnType" 之间哪个是正确的用法,但希望这会为某人指明正确的方向。

您的解决方法正是我们想要的设计。您可以设置精度、比例、最大长度、unicode/ansi、fixed/variable 长度等类型,而不是一堆 "facets"。我们决定保持简单:如果默认类型映射不是您想要的,请告诉我们要使用的类型。已经有人讨论过要收回这个决定并重新引入 "facets"。如果你对此有强烈的感觉,我会鼓励你create a new issue

另请注意,目前类型映射中还有许多其他错误,但它们应该会在我们发布 beta5 时修复。

根据 EF RC1,显示的示例似乎已过时。

下面是我在小数字段上设置精度的方法。

假设我有一个实体

public class Review
{
    public int ReviewId { get; set; }
    public decimal TotalScore { get; set; } //I want a precision field in DB
    public DateTime CreatedOn { get; set; }
    [Timestamp]
    public byte[] RowVersion { get; set; }
}

然后在我的上下文 class 中,在创建模型时,我实例化映射(我可以在那里进行映射,但我喜欢将它们分开)

public class MyDbContext : DbContext
{
    public MyDbContext(DbContextOptions<MyDbContext> options ) : base(options)
    {
    }

    public DbSet<Review> Reviews { get; set; }
    //etc.

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //Mappings
        new ReviewMap(modelBuilder.Entity<Review>());
        //etc..
    }
}

然后是映射。请记住使用模型扩展所在的命名空间:

using Microsoft.Data.Entity; //here is where the extensions are
public class ReviewMap
{
    public ReviewMap(EntityTypeBuilder<Review> entityBuilder)
    {
        entityBuilder.HasKey(r => r.ReviewId);

        //Using the column type extension
        entityBuilder.Property(r => r.TotalScore)
            .HasColumnType($"decimal(5,2)")
            .IsRequired(true);

        //and this has nothing to do with the example but it's interesting
        //to show how to use Sql command to automatically fulfil a value 
        //when adding a new Entity
        entityBuilder.Property(r => r.CreatedOn)
            .ValueGeneratedOnAdd()
            .HasDefaultValueSql("GETUTCDATE()")
            .IsRequired(true);
    }
}