shk*_*apo 8 c# ef-migrations entity-framework-core asp.net-core
我遇到了一个问题,我无法访问SQL脚本来应用迁移.这是我的迁移代码:
public partial class AddSomethingMigration : Migration
{
private const string MIGRATION_SQL_SCRIPT_FILE_NAME = @"Migrations\Scripts\20170710123314_AddSomethingMigration.sql";
protected override void Up(MigrationBuilder migrationBuilder)
{
string sql = Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, MIGRATION_SQL_SCRIPT_FILE_NAME));
migrationBuilder.Sql(File.ReadAllText(sql));
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当我在本地计算机上使用程序包管理器控制台时,一切正常.但是当我部署到环境中时,我得到了与文件的差异.
我可以自动通过EF迁移运行我的静态SQL脚本,还是应该在代码中内嵌SQL查询?
shk*_*apo 14
我找到了这个问题的几个答案.
将脚本添加为项目资源并使用它:
string sql = Resources._20170630085940_AddMigration;
migrationBuilder.Sql(sql);
Run Code Online (Sandbox Code Playgroud)这个选项不太好,因为.sql会嵌入程序集中.
如果您使用.csproj结构的Net Core项目,则可以将itemgroup添加到xml:
<ItemGroup> <Content Include="Migrations\**\*.sql" CopyToPublishDirectory="PreserveNewest" /><!-- CopyToPublishDirectory = { Always, PreserveNewest, Never } --></ItemGroup>
Run Code Online (Sandbox Code Playgroud)然后指定文件的路径,如:
Path.Combine(AppContext.BaseDirectory, relativePath)
Run Code Online (Sandbox Code Playgroud)
Yan*_*lla 11
我喜欢做的是将 SQL 脚本作为资源嵌入到程序集中,以便程序集不依赖于任何外部文件。我已经使用 Visual Studio Community 2019 16.4.2 测试了这种方法。就我而言,DbContext它保留在 .NET Standard 2.0 库中,而我的 Web 应用程序正在运行 .NET Core 2.2。
首先你需要创建一个迁移文件:
添加新的迁移:
Add-Migration RunSqlScript
在迁移文件夹中添加一个Sql Script(为了方便起见,我将其命名为与迁移文件相同的前缀)
在文件属性窗口中,确保构建操作是“嵌入式资源”。请注意,我们不需要复制到输出文件夹,因为 sql 脚本将嵌入到程序集中。
更新RunSqlScript迁移中的 Up 方法
var assembly = Assembly.GetExecutingAssembly();
string resourceName = typeof(RunSqlScript).Namespace + ".20191220105024_RunSqlScript.sql";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(stream))
{
string sqlResult = reader.ReadToEnd();
migrationBuilder.Sql(sqlResult);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中,我已将此代码重新分解为实用程序方法。为简洁起见,我没有进行这种重构。
更新:
我上面提到的重构代码:
var assembly = Assembly.GetExecutingAssembly();
string resourceName = typeof(RunSqlScript).Namespace + ".20191220105024_RunSqlScript.sql";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(stream))
{
string sqlResult = reader.ReadToEnd();
migrationBuilder.Sql(sqlResult);
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
public static class MigrationUtility
{
/// <summary>
/// Read a SQL script that is embedded into a resource.
/// </summary>
/// <param name="migrationType">The migration type the SQL file script is attached to.</param>
/// <param name="sqlFileName">The embedded SQL file name.</param>
/// <returns>The content of the SQL file.</returns>
public static string ReadSql(Type migrationType, string sqlFileName)
{
var assembly = migrationType.Assembly;
string resourceName = $"{migrationType.Namespace}.{sqlFileName}";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
{
throw new FileNotFoundException("Unable to find the SQL file from an embedded resource", resourceName);
}
using (var reader = new StreamReader(stream))
{
string content = reader.ReadToEnd();
return content;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以首先在同一项目中创建一个辅助方法:
public static class SqlFileTrigger
{
public static string GetRawSql(string sqlFileName)
{
var baseDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Migrations");
var path = Path.Combine(baseDirectory, sqlFileName);
return File.ReadAllText(path);
}
}
Run Code Online (Sandbox Code Playgroud)
然后添加您的迁移。假设您添加为:
add-migration AddDefaultUser 然后生成如下:
现在添加 2 个具有相同名称且后缀为 _Up 和 _Down 的 sql 文件(包括要运行的 SQL 语句,例如插入记录等)。所以它会是这样的:
然后在迁移文件的 UP 和 DOWN 方法中,使用 MigrationBuilder 对象调用它们。所以你的迁移文件将如下所示:
public partial class AddDefaultUser : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(SqlFileTrigger.GetRawSql("20220918043843_AddDefaultUser_Up.sql"));
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(SqlFileTrigger.GetRawSql("20220918043843_AddDefaultUser_Down.sql"));
}
}
Run Code Online (Sandbox Code Playgroud)
PS:请确保设置 SQL 文件属性以COPY ALWAYS确保它们已部署。
希望能帮助到你..
| 归档时间: |
|
| 查看次数: |
7145 次 |
| 最近记录: |