asp.net mvc 4模型问题(实体框架) - 一个数据库的多个上下文

时间:2013-09-17 09:28:30

标签: asp.net entity-framework asp.net-mvc-4

我正在使用asp.net mvc 4进行编程,并且我在使用默认情况下创建的模板,当您选择互联网应用程序模板时,这将带有一个模型,模型文件夹下的AccountModels.cs,它被初始化为这样(AccountModels。 CS):

public class UsersContext : DbContext
{
    public UsersContext()
        : base("DefaultConnection")
    {
    }

    public DbSet<UserProfile> UserProfiles { get; set; }
}

(...) // tables definition

但不是我需要添加到默认情况下创建的同一个数据库中存储我的应用程序配置的一些表但我不想在创建AccountModels.cs的默认文件中创建我的配置表,我想将它们分开以便知道它们是与app配置相关,所以我在Models文件夹下创建了另一个名为AppConfigModels.cs的文件,其中包含了这个(一部分):

public class ConfigContext : DbContext
{
    public ConfigContext()
        : base("DefaultConnection")
    {
    }

    public DbSet<Config1> Config1{ get; set; }
    public DbSet<Config2> Config2{ get; set; }
}

(...) // tables definition

这与默认名称相同,我希望它指向同一个数据库,因为我希望在同一个数据库中创建我的应用程序配置表。

默认情况下,实体框架不会更新数据库,如果它被创建,所以我重命名现有数据库或删除所以实体框架再次创建(我知道如果模型更改,我可以将行为更改为实体框架更新数据库,但在这种情况下我已经解释了)。因此它在文件InitializeSimpleMembershipAttribute.cs中的OnActionExecuting开始并跟随:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
{
    private static SimpleMembershipInitializer _initializer;
    private static object _initializerLock = new object();
    private static bool _isInitialized;

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Ensure ASP.NET Simple Membership is initialized only once per app start
        LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock); <---- HERE IT CRASHES
    }

    (...)
}

提出的错误是:

The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588

如何摆脱这个?我希望将我的表分隔在不同的文件中,并使用另一个上下文指向同一个数据库。

3 个答案:

答案 0 :(得分:4)

来自Entity Framework团队的Arthur Vickers推荐以下模式......

不要在app.config文件中为多个上下文指定单独的连接字符串,只需设置一个字符串并为其指定通用名称即可。

<connectionStrings>
    <add name="MyDBContext" connectionString="Your conn string here" providerName="System.Data.SqlClient" />
</connectionStrings>

然后创建一个将使用连接字符串的基本上下文类:

using System.Data.Entity; 

    namespace DataLayer
    {
        public class BaseContext<TContext> : DbContext where TContext : DbContext
        {
            static BaseContext()
            {
                Database.SetInitializer<TContext>(null); 
            }
            protected BaseContext()
                : base("name=MyDBContext")
            {
            }

        }
    }

现在,在每个上下文中继承此基本行为(例如):

namespace DataLayer.Models
{
    public class OrderContext : BaseContext<OrderContext>

…

namespace DataLayer.Models
{
    public class ProductContext : BaseContext<ProductContext>
…

答案 1 :(得分:1)

使用EF5,如果将上下文放在单独的项目中,则可以使用多次迁移。

使用EF6支持multiple contexts for DB。 EF4 / 5不喜欢指向同一项目中同一数据库的多个上下文。

答案 2 :(得分:0)

数据库是否设置了UsersProfile表?如果没有,SimpleMembership将不会初始化。架构如下(不确定此查询是否会运行):

CREATE TABLE [dbo].[UserProfile](
[UserId] [int] IDENTITY(1,1) NOT NULL,
[UserName] [varchar](75) NOT NULL,
)