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:
没有使用 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);
}
}
我一直在尝试弄清楚如何为 EF7 (Beta 4) 设置小数精度,但没有成功。
我期待做这样的事情:
modelBuilder.Entity<SomeClass>().Property(p => p.DecimalProperty).Precision(10, 6)
这似乎不可用,但我能够在 GitHub 的存储库中找到以下 class:
没有使用 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);
}
}