我尝试将Entity-Framework实现到我的项目中!我的项目是基于插件的,所以我不知道我必须将哪个对象保存到数据库。
我已经实现了它:
public class DatabaseContext : DbContext
{
public DatabaseContext() : base()
{
Database.Initialize(true);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
foreach( PluginDto plugin in BackendContext.Current.PluginManager._plugins) {
foreach(Type obj in plugin.plugin.getPluginDatabaseObjects())
{
Type typ = typeof(EntityTypeConfiguration<>).MakeGenericType(obj);
List<MethodInfo> l = modelBuilder.GetType().GetMethods().ToList<MethodInfo>();
MethodInfo m_Entitiy = modelBuilder.GetType().GetMethod("Entity").MakeGenericMethod(new Type[] { obj });
var configObj = m_Entitiy.Invoke(modelBuilder, null);
MethodInfo m_ToTable = configObj.GetType().GetMethod("ToTable", new Type[] { typeof(String) });
m_ToTable.Invoke(configObj, new object [] { obj.Name });
}
}
base.OnModelCreating(modelBuilder);
}
}
但是当我做出改变时,我得到了这个例外:
支持&#39; DatabaseContext&#39;自从以来情境发生了变化 数据库已创建。考虑使用Code First Migrations进行更新 数据库(http://go.microsoft.com/fwlink/?LinkId=238269)。
此错误完全符合逻辑。数据库不同步,但我将如何获得更新?我读过这个:
var config = new DbMigrationsConfiguration<MyContext> { AutomaticMigrationsEnabled = true };
var migrator = new DbMigrator(config);
migrator.Update();
但我不知道如何以及在何处正确使用它! 非常感谢你!
EDIT1: 当我尝试:Enable-Migrations -EnableAutomaticMigrations
时我收到了这个错误:
System.NullReferenceException: Object reference not set to an instance of an object.
at SOM.Backend.database.DatabaseContext.OnModelCreating(DbModelBuilder modelBuilder) in C:\Users\Flo\Documents\Visual Studio 2015\Projects\SOM\Backend\BackendService\BackendService\database\DatabaseContext.cs:line 26
at System.Data.Entity.Internal.LazyInternalContext.CreateModelBuilder()
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.LazyInternalContext.MarkDatabaseInitialized()
at System.Data.Entity.Database.Initialize(Boolean force)
at SOM.Backend.database.DatabaseContext..ctor() in C:\Users\Flo\Documents\Visual Studio 2015\Projects\SOM\Backend\BackendService\BackendService\database\DatabaseContext.cs:line 21
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Data.Entity.Infrastructure.DbContextInfo.CreateInstance()
at System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbProviderInfo modelProviderInfo, AppConfig config, DbConnectionInfo connectionInfo, Func`1 resolver)
at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext, DatabaseExistenceState existenceState, Boolean calledByCreateDatabase)
at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration)
at System.Data.Entity.Migrations.Design.MigrationScaffolder..ctor(DbMigrationsConfiguration migrationsConfiguration)
at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldInitialCreate(String language, String rootNamespace)
at System.Data.Entity.Migrations.EnableMigrationsCommand.<>c__DisplayClass2.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
EDIT2:
<connectionStrings>
<add name="DatabaseContext" providerName="System.Data.SqlServerCe.4.0" connectionString="Data Source=SOM_db.sdf;Max Database Size=1024" />
</connectionStrings>
答案 0 :(得分:8)
你要求的是可行的,但有一些限制。
<强>解决方案:强>
首先,删除
Database.Initialize(true);
来自构造函数。构造函数被多次调用,包括迁移。
其次,创建一个像这样的配置类
internal sealed class DataContextConfiguration : DbMigrationsConfiguration<DataContext>
{
public DataContextConfiguration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
ContextKey = "DataContext";
}
}
然后按如下所示更改构造函数:
public DataContext()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DataContext, DataContextConfiguration>());
}
你完成了。将自动创建/更新插件中实体类型的数据库表。
回顾一下,基本上这是一个标准的Code First方法,启用了自动迁移,但是OnModelCreating
覆盖内部的动态实体类型注册/配置。
<强>限制:强>
如果未设置AutomaticMigrationDataLossAllowed = true
,则删除现有插件时,EF将生成异常,因为不允许删除相应的表。如果你这样做,插件表将被删除,所以如果插件再次添加,它将从零开始。
只能使用数据注释配置插件实体。如果你想给他们完全控制,你可能需要更改插件界面,而不是采用实体类型,调用一些方法并改为传递DbModelBuilder
,这样他们就可以使用Fluent API配置他们的实体类型本身。
答案 1 :(得分:1)
执行命令
Update-Database –Verbose
如果失败,请将邮件粘贴为评论。
答案 2 :(得分:1)
public class myContext : DbContext
{
public DbSet<myTable> myTables { get; set; }
public myContext() : base("myConStr") { }
public void UpdateDatabase()
{
var Migrator = new DbMigrator(new Migrations.Configuration(){ TargetDatabase = new DbConnectionInfo(this.Database.Connection.ConnectionString, "System.Data.SqlClient") });
IEnumerable<string> PendingMigrations = Migrator.GetPendingMigrations();
foreach (var Migration in PendingMigrations)
Migrator.Update(Migration);
}
}
static void Main(string[] args)
{
var db = new myContext();
db.UpdateDatabase();
}
答案 3 :(得分:0)
我不认为使用这种方法可以使用EF6。
EF需要DbSets位于上下文类中,因此您需要动态生成DatabaseContext
类(基于插件实体),编译并加载它。
之后,您可以开始考虑迁移(自动或手动,有或没有允许数据丢失等)
使用刚创建的DatabaseContext也应该很简单(你应该可以通过标准DbContext
接口访问你的类)