我的客户端有一个存储SQL Server小数的标准,带有十进制(13,4)规范.结果,在一个非常大且仍在增长的模式中,我有近百个这样的语句:
builder.Entity<MyObject>()
.Property(x => x.MyField1)
.ForSqlServerHasColumnType("decimal(13,4)");
builder.Entity<MyObject>()
.Property(x => x.MyField2)
.ForSqlServerHasColumnType("decimal(13,4)");
builder.Entity<MyObject2>()
.Property(x => x.MyField1)
.ForSqlServerHasColumnType("decimal(13,4)");
Run Code Online (Sandbox Code Playgroud)
如果有一个功能,我可以直接告诉EF所有小数都应该是十进制(13,4)默认情况下,我想使用它.如果没有,我可以使用反射循环遍历模型中的每个对象/属性,所以我可以在几个语句中执行此操作吗?
就像是:
foreach(var efObj in EntityFrameWorkObjects)
{
foreach (var objProperty in efObj)
{
if (objProperty is decimal || objProperty is decimal?)
{
builder.Entity<efObj>()
.Property(x => x.efObj)
.ForSqlServerHasColumnType("decimal(13,4)");
}
}
}
Run Code Online (Sandbox Code Playgroud)
反射似乎是一个很好的方法,因为那时我可以实现一些其他约定,如果一个对象有一个名称和描述,名称是必需的,并限制为256个字符.
更新: 我按照Ivan评论中的链接进行了调整,并对其进行了调整,这对我有用:
foreach (var p in builder.Model
.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p =>
p.ClrType == typeof(decimal) ||
p.ClrType == typeof(decimal?)))
{
p.SqlServer().ColumnType = "decimal(13,4)";
}
Run Code Online (Sandbox Code Playgroud)
不久之后,他提供了一个完整的答案,我稍微改了一下,使用十进制和可以为零的小数:
foreach (var pb in builder.Model
.GetEntityTypes() …Run Code Online (Sandbox Code Playgroud) 我有一个基本模型:
public abstract class Status
{
public string updateUserName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后是扩展上面定义的基本模型的模型:
public class Item : Status
{
public int Id { get; set; }
public string Description { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后我为每个定义了配置类:
public class ItemConfiguration : IEntityTypeConfiguration<Item>
{
public void Configure(EntityTypeBuilder<Item> builder)
{
builder.ToTable("Item", "dbo").HasKey(c => c.Id);
builder.Property(c => c.Description).IsRequired().HasMaxLength(100);
}
}
public class StatusConfiguration : IEntityTypeConfiguration<Status>
{
public void Configure(EntityTypeBuilder<Status> builder)
{
builder.Property(c => c.updateUserName).IsRequired().HasMaxLength(50);
}
Run Code Online (Sandbox Code Playgroud)
现在,我有以下Context类:
public class TestDbContext : DbContext
{
public …Run Code Online (Sandbox Code Playgroud) sql-server ef-code-first entity-framework-core ef-fluent-api asp.net-core-2.0
由于Entity Framework将nvarchar(max)字符串默认用作默认值,因此我想将其他内容设置为默认值。
在Entity Framework 6.1.3中,我可以这样修改OnModelCreating(DbModelBuilder modelBuilder):
modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
modelBuilder.Properties<DateTime>().Configure(c => c.HasPrecision(0));
modelBuilder.Properties<string>()
.Configure(s => s.HasMaxLength(256).HasColumnType("nvarchar"));
Run Code Online (Sandbox Code Playgroud)
如果随后我使用数据注释修改了属性,EF则改用这些值,如下所示:
[MaxLength(128)]
public string Name { get; set; }
[Column(TypeName = "nvarchar(MAX)")]
[MaxLength]
public string Comment { get; set; }
Run Code Online (Sandbox Code Playgroud)
但是使用Microsoft.EntityFrameworkCore.SqlServer 2.1.0我不能做到这一点,我也不能使用Conventions。
我可以这样解决,datetime但是如果我尝试对字符串执行相同的操作,则迁移将表明type: "nvarchar(256)", maxLength: 128是否使用例如数据注释。我该如何解决?
foreach (var property in modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p => p.ClrType == typeof(DateTime)))
{
property.Relational().ColumnType = "datetime2(0)";
}
Run Code Online (Sandbox Code Playgroud) 在我的EF核心项目中,我有一些从基类DBEntity继承的实体:
public abstract class DBEntity
{
public int Id { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime UpdatedOn { get; set; }
public EntityStatus EntityStatus { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我想为从DBEntity继承的每个实体设置一些具有默认值的特定属性.目前我正在使用此代码:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var entities = modelBuilder.Model
.GetEntityTypes()
.Where(w => w.ClrType.IsSubclassOf(typeof(DBEntity)))
.Select(p => modelBuilder.Entity(p.ClrType));
foreach (var entity in entities)
{
entity
.Property("CreatedOn")
.HasDefaultValueSql("GETDATE()");
entity
.Property("UpdatedOn")
.HasComputedColumnSql("GETDATE()");
entity
.Property("EntityStatus")
.HasDefaultValue(EntityStatus.Created);
}
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我不想使用字符串常量指定属性名称(对于重构等不好).
有没有办法循环从DBEntity继承的实体并使用属性表达式配置默认值,如下所示:
foreach (var entity in entities)
{
entity
.Property(k …Run Code Online (Sandbox Code Playgroud)