简体   繁体   English

放置Database.SetInitializer的地方

[英]Place to put Database.SetInitializer

I'm working on a project that at can end up with multiple UI versions / variants, but so far I've got two subprojects in my solution Web - containing Web interface with ASP.NET MVC. 我正在开发一个最终可能有多个UI版本/变体的项目,但到目前为止,我的解决方案Web中有两个子项目 - 包含ASP.NET MVC的Web界面。 Service project is place where I have my database context and models defined. 服务项目是我定义数据库上下文和模型的地方。

My Goal is to have minimum or possibly no references to EF specific code in my Web project. 我的目标是在我的Web项目中对EF特定代码进行最少或可能没有引用。 I want it to be independent so when I switch the dlls with service backend ( from let say SQL to XML or MySQL ) I shouldn't make multiple modifications in my MVC project. 我希望它是独立的,所以当我用服务后端切换dll(从假设SQL到XML或MySQL)时,我不应该在我的MVC项目中进行多次修改。

This is how it looks : 这是它的样子:

项目布局

My Questions are: - so far I've found no example of using Database.SetInitializer in other place than Global.asax. 我的问题是: - 到目前为止,我没有找到在Global.asax之外的其他地方使用Database.SetInitializer的示例。 I'd like to put database re-creation if model changed in my factory-like DatabaseContextProvider class or in service class that pulls out data from context and provides it to the UI with DTOs. 如果模型在我的工厂类似的DatabaseContextProvider类或服务类中更改,从内容中提取数据并将其提供给具有DTO的UI,我想放置数据库重新创建。 Are there any cons of that location ? 那个地方有没有缺点? - I would like to have the context's connectionString to be configurable with Properties/Settings.settings file - is that reasonable ? - 我想让上下文的connectionString可以使用Properties / Settings.settings文件进行配置 - 这是否合理?

To avoid the coupling, I would prefer not to set the initializer outside the Assembly that contains the DataContext. 为了避免耦合,我宁愿不在包含DataContext的Assembly之外设置初始化程序。 So, I added a static constructor for the DataContext. 所以,我为DataContext添加了一个静态构造函数。 This way every project referencing this Assembly will enjoy the initializer without explicitly setting it, and the initializer is set only once per process. 这样,引用此程序集的每个项目都将享受初始化程序而无需显式设置它,并且初始化程序仅在每个进程中设置一次。

static MyDataContext()
{
   Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDataContext, Configuration>());
}

The connection string will of course be taken from the application configuration file. 连接字符串当然将从应用程序配置文件中获取。

You would need a mechanism to call the Database.SetInitializer method before the very first usage of the DbContext . 在第一次使用DbContext之前,您需要一种机制来调用Database.SetInitializer方法。 That is why its usually called in the Global.asax file. 这就是它通常在Global.asax文件中调用的原因。

You can create a class with an initialization method in your tm.Service project and call it in the Application_Start method and put the Database.SetInitializer in that initialization method. 您可以在tm.Service项目中使用初始化方法创建一个类,并在Application_Start方法中调用它,并将Database.SetInitializer放入该初始化方法中。

Its OK to supply the connection string from a setting file. 可以从设置文件中提供连接字符串。

I put it on the DbContext constructor and works for me. 我把它放在DbContext构造函数上并为我工作。

public myDbContext() : base(connectionToDatabase) {
        Database.SetInitializer<myDbContext>(null);
    }

The solution above will work, but it is not as efficient as the following code: 上面的解决方案可行,但效率不如以下代码:

  protected void Application_Start()
    {
        Database.SetInitializer<myDbContext>(null);
    }

In my case I don't have a reference of my DAL on the UI and for that reason what I did is, I create a EntityFramework config and register my setting using using reflection. 在我的情况下,我没有在UI上引用我的DAL,因此我做的是,我创建了一个EntityFramework配置并使用反射注册我的设置。

 protected void Application_Start()
    {           
        EntityFrameworkConfig.RegisterSettings();
    }


 public static class EntityFrameworkConfig
{
    public static void RegisterSettings()
    {
        // Use the file name to load the assembly into the current
        // application domain.
        Assembly a = Assembly.Load("MyAssembly");
        // Get the type to use.
        Type myType = a.GetType("MyType");
        // Get the method to call.
        MethodInfo myMethod = myType.GetMethod("MySettingsMethod");
        // Create an instance.
        object obj = Activator.CreateInstance(MyType);
        // Execute the method.
        myMethod.Invoke(obj, null);
    }
}

  public void Configurations()
    {
      //Other settings
        Database.SetInitializer<myDbContext>(null);
    }

Updated 更新

With Entity Framework 6, now you can use the NullDatabaseInitializer 使用Entity Framework 6,现在可以使用NullDatabaseInitializer

Database.SetInitializer(new NullDatabaseInitializer<MyDbContext>());

Microsoft made it possible, for EF6 onwards, to configure one initializer per database context in the config file of the application. 对于EF6以上,Microsoft使得在应用程序的配置文件中为每个数据库上下文配置一个初始化程序成为可能。 See the last section on this Microsoft page: https://msdn.microsoft.com/en-us/data/jj556606.aspx 请参阅此Microsoft页面的最后一部分: https//msdn.microsoft.com/en-us/data/jj556606.aspx

This, like the "Global.asax" approach, has the advantage that eg unit test projects can use a different initializer for the same database context. 这与“Global.asax”方法一样,具有以下优点:例如,单元测试项目可以对同一数据库上下文使用不同的初始化程序。

单击Global.asax页面,您将找到Application_Start()方法。请在此方法之后通过以下代码。为了支持此代码,请使用System.Data.Entity;

Database.SetInitializer<namespace.modelclass>(null);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Database.SetInitializer中的DropCreateDatabaseIfModelChanges - DropCreateDatabaseIfModelChanges in Database.SetInitializer Database.SetInitializer是否不播种数据库? - Database.SetInitializer is not seeding the database? 使用Database.SetInitializer避免Shotgun手术 - Avoiding Shotgun Surgery with Database.SetInitializer 我可以将我的Database.SetInitializer调用放入具有基本字符串而不是静态构造函数的上下文构造函数中吗? - Can I put my Database.SetInitializer call in the context constructor with the base string instead of a static constructor? Database.SetInitializer(new MigrateDatabaseToLatestVersion <Context, Configuration> ()); 错误 - Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context, Configuration>()); Error Database.SetInitializer的目的 <ArContext> (null)在存储库中? - purpose of Database.SetInitializer<ArContext>(null) inside of repository? 为什么EF4.1 CodeFirst即使没有“ Database.SetInitializer &lt;&gt;()”调用也会创建数据库? - Why is EF4.1 CodeFirst is creating a database even without a `Database.SetInitializer<>()` call? 实体框架CTP4:在哪里放置SetInitializer? - Entity Framework CTP4: where to put SetInitializer? WebSecurity.InitializeDatabaseConnection,SetInitializer和Database.Initialize - WebSecurity.InitializeDatabaseConnection, SetInitializer and Database.Initialize 在 MySql.Data.EntityFrameworkCore 中找不到数据库 SetInitializer - Database SetInitializer is not found in MySql.Data.EntityFrameworkCore
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM