我正在构建一个需要在运行时创建 EntityFrameWorkCore DbContext 然后进行迁移的应用程序,如果我不使用 dbContext.Database.Migrate() 方法,下面的代码将编译并运行,但如果我这样做了,我会得到一个诊断错误关于缺少指令/参考。
错误 CS1061:“DatabaseFacade”不包含“Migrate”的定义,并且找不到接受“DatabaseFacade”类型的第一个参数的可访问扩展方法“Migrate”(您是否缺少 using 指令或程序集引用?)
如果我只是用我的项目中的代码创建一个文件,我也不会收到任何错误。据我所知,“DatabaseFacade”是 EntityFrameWorkcore.Infrastructure 的一部分,如果 Microsoft.EntityFrameworkCore 应该是它的一部分。
这些是我在 CSharpCompiler 中包含的参考:
"System"
"System.Console"
"System.Runtime"
"System.Private.CoreLib"
"System.Linq"
"System.Data.Common"
"System.Data"
"System.Data.SqlClient"
"System.ComponentModel"
"Microsoft.EntityFrameworkCore"
"Microsoft.EntityFrameworkCore.SqlServer"
"netstandard"
我正在使用 Microsoft.CodeAnalysis 创建一个 CSharpCompilation,然后发出我在运行时调用 main 方法的程序集。
我什至尝试用反射调用 migrate() 方法来绕过智能,但是 GetMethod("Migrate") 返回 null,所以它显然不存在。
这是我试图编译和使用运行时的代码(简化):
using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using mothership_shared.Data;
using mothership_shared.Enums;
using mothership_shared.Interfaces;
using mothership_shared.Models;
using static mothership_shared.Attributes.PropertyCalculations;
using static mothership_shared.Attributes.PropertyTypes;
using static mothership_shared.Attributes.Settings;
using static mothership_shared.Data.SqlServiceClasses;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace mothership_shared.MigratorProgram
{
public class Program
{
static void Main(string[] args)
{
SqlConnectionSettings sqlConnectionSettings = new SqlConnectionSettings()
{
ServerUrl = args[0],
Catalog = args[1],
User = args[2],
Password = args[3],
};
var dbContext = new ApplicationDbContext(sqlConnectionSettings.AppConnection);
ISql sqlService = new SqlService();
var request = new DeleteMigrationHistory.Request()
{
ConnectionSettings = sqlConnectionSettings,
};
sqlService.DeleteMigrationHistory(request);
dbContext.Database.Migrate();
}
public void Run(string[] args)
{
Main(args);
}
public class ApplicationDbContext : DbContext
{
private readonly string _connectionString;
public ApplicationDbContext(string connectionString)
{
_connectionString = connectionString;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(_connectionString);
}
public DbSet<SimpleEntity> SimpleEntity { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var allTypes = Assembly.GetCallingAssembly().GetTypes();
var EntityTypes = allTypes.Where(t => t.BaseType == typeof(BaseEntity));
foreach (var t in EntityTypes)
{
var crud = t.GetCustomAttribute<CRUDAttribute>();
var properties = t.GetProperties();
foreach (var p in properties)
{
IsObjectAttribute otm = p.GetCustomAttribute<IsObjectAttribute>();
if (otm != null)
{
if (crud.ClassType != ClassType.MTM)
{
modelBuilder.Entity(t)
.HasOne(p.PropertyType, p.Name)
.WithMany(otm.WithMany)
.OnDelete(otm.DeleteBehavior);
}
else
{
modelBuilder.Entity(t)
.HasOne(p.PropertyType, p.Name)
.WithMany(otm.WithMany)
.OnDelete(DeleteBehavior.Cascade);
}
};
IsTimeSpanAttribute ts = p.GetCustomAttribute<IsTimeSpanAttribute>();
if (ts != null)
{
modelBuilder.Entity(t)
.Property(p.Name)
.HasConversion(new TimeSpanToTicksConverter());
}
}
}
}
}
[CRUDAttribute(ClassType.Referal)]
[HeaderAttribute("Simple entity", "Simple entitys", 0)]
[IconAttribute("ms-Icon--Document")]
[MenuAttribute("Test menu")]
[TooltipAttribute("This is a model that contains all simple propertytypes")]
public class SimpleEntity : BaseEntity
{
[IsTextAttribute(false)]
[HeaderAttribute("Text", "Texts", 0)]
[PriorityAttribute(1)]
[TooltipAttribute("This is a text property")]
[IconAttribute("ms-Icon--Text")]
[DefaultValueAttribute("This is the defaultvalue")]
public string TextProperty { get; set; }
}
}
}