代码首先创建表

时间:2013-04-01 16:22:05

标签: c# asp.net-mvc-4 entity-framework-5 ef-migrations

我正在关注this教程,我尝试在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>

[/编辑]

Configuration.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");
    }
  }
}

1 个答案:

答案 0 :(得分:15)

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

  

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

您现有的迁移尝试针对数据库的旧副本运行 - 我认为已经针对“空数据库”优化了上升/下降。

您需要针对您附加的Db副本运行迁移(添加迁移) - 这将创建“差异”并且只更新您的Db(始终 make当然可以备份,因为它可能会丢弃/更改等)。

或者如果可能的话,清空您的Db - 然后重新开始。

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

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

MVC3 and Code First Migrations - "model backing the 'blah' context has changed since the database was created"

修改
另请查看此答案AutomaticMigrationsEnabled false or true?

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

  

我总是采取一些措施来清理迁移:

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

...稍后(后续迁移):
- Add-Migration SomeOther1
- 更新 - 数据库 - 强制-Verbose
...让你保持你的Db同步 - 即小心'移动Db',手动调整等等(在这种情况下看另一篇文章)

结合其他事情:

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

连接:

请参阅我的这篇文章Migration does not alter my table
简而言之 - 您的连接被命名为您的上下文+您的项目 - 如果没有另外指定。它来自您的DbConfig构造函数 - 或app.config(连接)。确保您正在查看“正确的数据库”(即您通过某个资源管理器查看的内容以及代码优先连接到的内容 - 可能是两个不同的东西)。

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