这是我的解决方案。我在 .Net Core 3.1 DLL 的 EF Core DbContext 中使用了它。它适用于自动迁移,并使用一个属性,该属性通过反射进行搜索。该属性包含默认的 sql 值,然后在 OnModelCreating() 中设置。
[AttributeUsage(AttributeTargets.Property)]
public class DefaultValueSqlAttribute : Attribute
{
public string DefaultValueSql { get; private set; } = "";
public DefaultValueSqlAttribute(string defaultValueSql)
{
DefaultValueSql = defaultValueSql;
}
}
public class Entity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("Id", Order=0)]
[DefaultValueSql("newId()")]
public Guid Id { get; set; }
[Column("DateCreated", Order = 100)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[DefaultValueSql("GETUTCDATE()")]
public DateTime DateCreated { get; set; } = DateTime.UtcNow;
}
[Table("tbl_User")]
public class User: Entity
{
[Required]
[Column(Order = 1)]
public string EMail { get; set; }
[Column(Order = 2)]
public string Name { get; set; }
[Column(Order = 3)]
public string Forename { get; set; }
[Column(Order = 4)]
public string Street { get; set; }
[Column(Order = 5)]
public string Postalcode { get; set; }
[Column(Order = 6)]
public string MobileNumber { get; set; }
}
- 第 3 步 - 将您的类添加到 DbContext
public DbSet<User> tbl_User { get; set; }
- 第 4 步 - 将此代码添加到您的 DbContext(您必须根据需要对其进行更改...) 它假定所有相关的数据类都存在于一个特定的程序集和一个特定的命名空间中。在我的例子中,它是一个 .NetStandard 2.0 DLL。
protected override void OnModelCreating(ModelBuilder mb)
{
//Uncomment this line, if you want to see what is happening when you fire Add-Migration
//Debugger.Launch();
base.OnModelCreating(mb);
OnModelCreatingAddDefaultSqlValues(mb);
}
private void OnModelCreatingAddDefaultSqlValues(ModelBuilder mb)
{
var assemblyName = "Ik.Shared";
var nameSpace = "Ik.Shared.Entities";
var asm = Assembly.Load(assemblyName);
//Read all types in the assembly Ik.Shared, that are in the namespace Ik.Shared.Entities
List<Type> types = asm.GetTypes().Where(p => p.Namespace == nameSpace).ToList();
//Read all properties in DatabaseContext, that are of type DbSet<>
var dbSets = typeof(DatabaseContext).GetProperties().Where(p => p.PropertyType.Name.ToLower().Contains("dbset")).ToList();
//A list of types, that are used as a generic argument in a DbSet<T>
List<Type> dbSetTypes = new List<Type>();
foreach (PropertyInfo pi in dbSets)
{
//Add the type of the generic argument from DbSet<T>
dbSetTypes.Add(pi.PropertyType.GetGenericArguments()[0]);
}
//For all types in Ik.Shared
foreach (Type t in types)
{
//If a type inherited from Entity AND the type itself is not Entity AND the type was used as DbSet<Type> in the DbContext
if (typeof(Entity).IsAssignableFrom(t) && t.Name != nameof(Entity) && dbSetTypes.Contains(t))
{
//Get all properties of that type
var properties = t.GetProperties().ToList();
foreach (var p in properties)
{
//Check if the property has the DefaultValueSqlAttribute
var att = p.GetCustomAttribute<DefaultValueSqlAttribute>();
if (att != null)
{
//If any property has the DefaultValueSqlAttribute, set the the value here. Done.
mb.Entity(t).Property(p.Name).HasDefaultValueSql(att.DefaultValueSql);
}
}
}
}
}
- 第 5 步 - 在 Visual Studio 的打包程序控制台中启动新的迁移
Add-Migration MI_000000 -StartupProject Ik.Ws.Login
- 第 6 步 - 查看结果:查看 defaultValueSql = Done
//This class was entirely created automatic. No manual changes.
public partial class MI_000000 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "tbl_User",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false, defaultValueSql: "newId()"),
EMail = table.Column<string>(type: "nvarchar(max)", nullable: false),
Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
Forename = table.Column<string>(type: "nvarchar(max)", nullable: true),
Street = table.Column<string>(type: "nvarchar(max)", nullable: true),
Postalcode = table.Column<string>(type: "nvarchar(max)", nullable: true),
MobileNumber = table.Column<string>(type: "nvarchar(max)", nullable: true),
DateCreated = table.Column<DateTime>(type: "datetime2", nullable: false, defaultValueSql: "GETUTCDATE()")
},
constraints: table =>
{
table.PrimaryKey("PK_tbl_User", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "tbl_User");
}
}
希望对你有所帮助或启发。