1

我正在尝试创建要重用的模块。例如,创建和处理用户操作(登录、注册等)、然后构建它并在其他项目中使用 dll 的 Membership 项目。

因此,在 Membership 项目中,我使用自己的命名空间创建了我的 POCO 类和 DataContext:

namespace CloudOne.Membership.Models
{
    public class SiteDataContext : DbContext
    {
        public DbSet<User> Users { get; set; }
        public DbSet<UserRole> UserRoles { get; set; }
        public DbSet<UserRoleJoin> UserRoleJoins { get; set; }

        // Twist our database
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            base.OnModelCreating(modelBuilder);
        }
    }

    public class SiteDataContextInitializer : DropCreateDatabaseAlways<SiteDataContext>
    {
        protected override void Seed(SiteDataContext context)
        {
            // users

            var user = new User { UserID = "UserA", Password = "D33177D41FD48F0027BD10D2689E8599", DateCreated=DateTime.Now, DateLastLogin = DateTime.Now };

            context.Users.Add(user);

            var roles = new List<UserRole>
            {
                new UserRole { RoleID = "Admin" },
                new UserRole { RoleID = "Editor" },
                new UserRole { RoleID = "Customer" },
                new UserRole { RoleID = "Guest" }
            };

            roles.ForEach(m => context.UserRoles.Add(m));

            var userRoleJoin = new UserRoleJoin { UserID = "UserA", RoleID = "Admin" };

            context.UserRoleJoins.Add(userRoleJoin);
        }
    }
}

然后我在一个主项目中使用,使用 CloudOne.Membership.dll 作为参考,主项目又有了自己的 Namespace、DataContext 和 seed:

namespace CloudOne.Models
{
    public class SiteDataContext : DbContext
    {
        public DbSet<Category> Categories { get; set; }
        public DbSet<Product> Products { get; set; }
        public DbSet<ProductPrice> ProductPrices { get; set; }
        public DbSet<ProductPicture> ProductPictures { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            base.OnModelCreating(modelBuilder);
        }
    }

    public class SiteDataContextInitializer : DropCreateDatabaseAlways<SiteDataContext>
    {
        protected override void Seed(SiteDataContext context)
        {
            // data seeding here

            context.SaveChanges();
        }
    }
}

然后我从 global.asax 调用两个初始化器

protected void Application_Start()
        {
            Database.SetInitializer<SiteDataContext>(new SiteDataContextInitializer());
            Database.SetInitializer<CloudOne.Membership.Models.SiteDataContext>(new CloudOne.Membership.Models.SiteDataContextInitializer());

            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }

现在的问题是,当我访问使用主项目类的页面时,它为主类中定义的 POCO 创建数据库(ModelFirst),并为主项目数据上下文中定义的数据播种,但它不创建 POCO 或种子对于会员资格。而且,当访问使用会员数据的页面时......它仅为会员重新创建数据库。

那么,我如何将会员资格(和其他模块)与主项目一起使用,而不必手动添加表、关系和播种,而不是在主项目中?

例如,主要项目是关于购物车的,为了使用会员模块,我必须复制 ShoppingCart DataContext 中的所有 POCO 类以及创建用户、角色等的种子部分。但是该代码已经在会员资格中。初始化程序,那么如何封装它,这样就不需要将所有模块的代码复制到主应用程序中就可以拥有包含所有表和数据的数据库?

4

1 回答 1

0

很有可能这是一个连接字符串问题,并且数据库实际上是在您期望的地方创建的。

我的猜测是您已经SiteDataContext在 web.config 中定义了连接字符串,但您没有明确定义CloudOne.Membership.Models.SiteDataContext连接字符串。

EF 将考虑这两个单独的 DbContexts —— 你不能简单地通过使类同名来合并它们。因此,它正在寻找单独的连接字符串与您分配的单独初始化指令一起使用。

我没有用 EF 4.1 尝试过这个,但我相信模型更改跟踪将防止两个上下文共享同一个物理数据库(如此处所述)。

简而言之,我相信您的直接问题是您没有使用连接字符串初始化您的成员资格上下文,因此它默认为本地。EF 将尝试在活动应用程序域(您的购物车网站)中查找具有您的上下文名称的连接字符串,因此它需要位于该站点的 web.config 中。

于 2012-06-18T12:42:05.693 回答