EFCore 脚手架数据库并在运行时迁移到另一个上下文
EFCore scaffold database and migrate to another context at runtime
最近我开始创建一些 PostgreSQL 到 Mdb/Accdb 数据库转换器。我设法以一种有点通用的方式做到了:
public static void TransferData<TSource, TDest>(DbContext sourceContext, DbContext destContext)
where TSource : class where TDest : class
{
destContext.Set<TDest>().AddRange(sourceContext.Set<TSource>().Select(_mapper.Map<TDest>));
}
同样以通用方式在 AutoMapper 中指定映射:
public void RegisterGenericMapping<TSource, TDest>() => CreateMap<TSource, TDest>();
foreach (var entityName in EntitiesList.DestinationDb)
{
var sourceType = ReflectionHelper.GetType($"{EntitiesList.sourceNamespace}.{entityName}"); // My helper class to search in all assemblies
var destType = ReflectionHelper.GetType($"{EntitiesList.destNamespace}.{entityName}");
typeof(MappingProfile).GetMethods().First(x => x.Name == nameof(RegisterGenericMapping))
.MakeGenericMethod(sourceType, destType).Invoke(this, null);
}
通过这种方式获取所需的实体列表:
public static List<string> DestinationDb = typeof(MsAccessContext).GetProperties()
.Where(x => x.PropertyType.Name == "DbSet`1")
.Select(x => x.PropertyType.GenericTypeArguments[0]?.Name).ToList();
public static string sourceNamespace = "DbConverter.NpgsqlSupport.Entities";
public static string destNamespace = "DbConverter.MsAccessSupport.Entities";
但问题是我的内核中还有模型。对于源上下文和目标上下文...如果不在运行前先进行数据库迁移并将相同的 类 粘贴到目标上下文,则无法使用它。
我想要实现的是摆脱上下文中的所有模型 类 和 DbSets' 类:
在运行时搭建源数据库并添加 DbSet,然后基于源搭建的模型创建目标模型和 DbSet,将迁移应用到目标数据库,然后开始该过程。
目前我的解决方案仅适用于一个 PREPARED 数据库。我需要在运行时为每个数据库自动准备它。
不要为此使用 EF。只需使用 ADO.NET DataReaders 和 DataTables。它们在没有设计时元数据的情况下也能完美工作。
最近我开始创建一些 PostgreSQL 到 Mdb/Accdb 数据库转换器。我设法以一种有点通用的方式做到了:
public static void TransferData<TSource, TDest>(DbContext sourceContext, DbContext destContext)
where TSource : class where TDest : class
{
destContext.Set<TDest>().AddRange(sourceContext.Set<TSource>().Select(_mapper.Map<TDest>));
}
同样以通用方式在 AutoMapper 中指定映射:
public void RegisterGenericMapping<TSource, TDest>() => CreateMap<TSource, TDest>();
foreach (var entityName in EntitiesList.DestinationDb)
{
var sourceType = ReflectionHelper.GetType($"{EntitiesList.sourceNamespace}.{entityName}"); // My helper class to search in all assemblies
var destType = ReflectionHelper.GetType($"{EntitiesList.destNamespace}.{entityName}");
typeof(MappingProfile).GetMethods().First(x => x.Name == nameof(RegisterGenericMapping))
.MakeGenericMethod(sourceType, destType).Invoke(this, null);
}
通过这种方式获取所需的实体列表:
public static List<string> DestinationDb = typeof(MsAccessContext).GetProperties()
.Where(x => x.PropertyType.Name == "DbSet`1")
.Select(x => x.PropertyType.GenericTypeArguments[0]?.Name).ToList();
public static string sourceNamespace = "DbConverter.NpgsqlSupport.Entities";
public static string destNamespace = "DbConverter.MsAccessSupport.Entities";
但问题是我的内核中还有模型。对于源上下文和目标上下文...如果不在运行前先进行数据库迁移并将相同的 类 粘贴到目标上下文,则无法使用它。
我想要实现的是摆脱上下文中的所有模型 类 和 DbSets' 类:
在运行时搭建源数据库并添加 DbSet,然后基于源搭建的模型创建目标模型和 DbSet,将迁移应用到目标数据库,然后开始该过程。
目前我的解决方案仅适用于一个 PREPARED 数据库。我需要在运行时为每个数据库自动准备它。
不要为此使用 EF。只需使用 ADO.NET DataReaders 和 DataTables。它们在没有设计时元数据的情况下也能完美工作。