4

我正在关注教程,并尝试在 userprofile 表中添加一些新列。我试图创建一个新表。

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

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

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string Mobile { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

[Table("TestTabel")]
public class TestTabel
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int TestId { get; set; }
    public string TestName { get; set; }
    public string TestMobile { get; set; }
}

比我尝试使用 update-database 命令在控制台更新数据库时,我得到了这个错误消息:

数据库中已经有一个名为“UserProfile”的对象。

未添加的新列和表均未添加。

我错过了什么?

[编辑] 我执行了 add-migration 和 update-database 命令,这就是结果(必须执行两次 update-database 命令,第二次详细说明)

PM> Add-Migration
cmdlet Add-Migration at command pipeline position 1
Supply values for the following parameters:
Name: test
Scaffolding migration 'test'.
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration 201304011714212_test' again.
PM> Update-Database
The project 'MVC4SimpleMembershipCodeFirstSeedingEF5' failed to build.
PM> Update-Database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Applying code-based migrations: [201304011714212_test].
Applying code-based migration: 201304011714212_test.
Running Seed method.
PM> Update-Database -verbose
Using StartUp project 'MVC4SimpleMembershipCodeFirstSeedingEF5'.
Using NuGet project 'MVC4SimpleMembershipCodeFirstSeedingEF5'.
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is: 'aspnet-MVC4SimpleMembershipCodeFirstSeedingEF5' (DataSource: ., Provider: System.Data.SqlClient, Origin: Configuration).
No pending code-based migrations.
Running Seed method.
PM>

[/编辑]

配置.cs:

    namespace MVC4SimpleMembershipCodeFirstSeedingEF5.Migrations
{
    internal sealed class Configuration : DbMigrationsConfiguration<UsersContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
        }

    protected override void Seed(UsersContext context)
    {
        WebSecurity.InitializeDatabaseConnection(
            "DefaultConnection",
            "UserProfile",
            "UserId",
            "UserName", autoCreateTables: true);

        if (!Roles.RoleExists("Administrator"))
            Roles.CreateRole("Administrator");

        if (!WebSecurity.UserExists("test"))
            WebSecurity.CreateUserAndAccount(
                "test",
                "password",
                new { Mobile = "+19725000374", FirstName = "test", LastName = "test" });

        if (!Roles.GetRolesForUser("test").Contains("Administrator"))
            Roles.AddUsersToRoles(new[] { "test" }, new[] { "Administrator" });
    }
  }
}

在 Filters 文件夹 1 cs 文件中:

namespace MVC4SimpleMembershipCodeFirstSeedingEF5.Filters
{
    [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);
        }
    private class SimpleMembershipInitializer
    {
        public SimpleMembershipInitializer()
        {
            Database.SetInitializer<UsersContext>(null);

            try
            {
                using (var context = new UsersContext())
                {
                    if (!context.Database.Exists())
                    {
                        // Create the SimpleMembership database without Entity Framework migration schema
                        ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
                    }
                }

                WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
            }
        }
    }
  }
}

连接字符串:

<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>

上次迁移:

namespace MVC4SimpleMembershipCodeFirstSeedingEF5.Migrations
{
    using System;
    using System.Data.Entity.Migrations;

public partial class test : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.TestTabel",
            c => new
                {
                    TestId = c.Int(nullable: false, identity: true),
                    TestName = c.String(),
                    TestMobile = c.String(),
                })
            .PrimaryKey(t => t.TestId);

    }

    public override void Down()
    {
        DropTable("dbo.TestTabel");
    }
  }
}
4

1 回答 1

17

我只是将这里的所有内容作为一个演练,让您的代码优先和迁移进行 - 攻击可能发生或可能不会发生的各种问题。注意:代码优先已被证明是非常可靠的——并且也可以在实时场景中解决——你只需要知道你在做什么。

最有可能的是,您的迁移和数据库基本上是不同步的。

您现有的迁移尝试针对数据库的旧副本运行 - 我猜是针对“空数据库”优化的起伏。

您需要针对您附加到的 Db 副本运行迁移(添加迁移) - 这将产生“差异”并且只是最新的 Db(当然,请始终确保备份,因为它可能会下降/改变等)。

或者如果可能的话,清空你的数据库——然后重新开始。

或者,如果实时 Db - 创建迁移 - 并Update-Database -Script在您的开发机器上运行 - 以生成完整的 Db - 或更改(这一切都非常粗糙,您需要根据您的情况进行调整)。然后通过运行脚本应用到您的“live Db”。

您也可以查看我之前关于同步的帖子...

MVC3 和 Code First 迁移 - “自从创建数据库以来,支持‘blah’上下文的模型已经改变”

编辑:
还要检查这个答案AutomaticMigrationsEnabled false 还是 true?

如果您的处事方式没问题,请将其添加AutomaticMigrationsEnabled = true;到您Configuration(也在 Migrations 文件夹下 - 为您创建)..

我经常做的几个步骤来清理迁移:

(最好先备份)
- Enable-Migrations -force (仅限第一次 - 这会删除 configuration.cs 和那里的任何“种子”!)
- AutomaticMigrationsEnabled = true;
- 从项目中手动删除现有迁移 (\Migrations)
- 此时重建项目
- Add-Migration Initial
- Update-Database -Force -Verbose

...稍后(后续迁移):
- Add-Migration SomeOther1
- Update-Database -Force -Verbose
...如果您保持 Db 同步 - 即小心“移动 Db”、手动调整等(以及这种情况见另一篇文章)

结合其他事情:

使用 PM 控制台...
- 从列表中选择您的项目,
- 确保您的“主 exe”(调用您的数据项目/程序集 - 或者如果控制台/应用程序则为同一个项目)- 设置为“启动”项目,
- 始终观看控制台评论 - 因为它可能正在尝试构建和访问不同的项目。

联系:

请参阅我的这篇文章迁移不会改变我的表
简而言之 - 您的连接命名为您的上下文 + 您的项目 - 如果未另行指定。它取自您的 DbConfig 构造函数 - 或 app.config(连接)。确保您正在查看“正确的数据库”(即您通过某些资源管理器查看的内容和代码优先连接的内容 - 可能是两个不同的东西)。

构建:
确保您的项目设置为“配置”以自动构建 - 这也可能是一个问题。

于 2013-04-01T16:47:38.910 回答