c# - 代码先创建表

标签 c# asp.net-mvc-4 entity-framework-5 entity-framework-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>

[/编辑]

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

最佳答案

我只是将所有内容都放在此处,作为让您的代码优先和迁移继续进行的演练 - 解决可能发生或可能不会发生的各种问题。注意:代码优先已被证明是非常可靠的 - 并且也可以通过实际场景解决 - 你只需要知道你在做什么。

Most likely, your migration and the database are basically out-of-sync.

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

您需要针对您附加到的 Db 的副本运行迁移(添加迁移)——这将创建一个“差异”并使您的 Db 保持最新(始终 ma​​ke当然要备份,因为它可能会丢失/更改等)。

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

或者如果实时 Db - 创建迁移 - 并在你的开发机器上运行 Update-Database -Script - 生成完整的 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 文件夹下 - 为您创建)..

Couple steps I always do to clean migrations:

(最好先备份)
- Enable-Migrations -force(仅限第一次 - 这会删除 configuration.cs 和那里的任何“种子”!)
- AutomaticMigrationsEnabled = true;
- 从项目 (\Migrations) 中手动删除现有迁移
- 此时重建项目
- 添加迁移初始
- 更新数据库 -Force -Verbose

...稍后(后续迁移):
- 添加迁移 SomeOther1
- 更新数据库 -Force -Verbose
...提供你保持你的 Db 同步 - 即小心“移动 Db”,手动调整等(在这种情况下请参阅另一篇文章)

结合其他的东西:

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

连接:

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

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

关于c# - 代码先创建表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15747162/

相关文章:

c# - 为什么派生类需要使用基类构造函数

c# - 使用 XmlSerializer 重命名平面 xml 数组中的数组项

c# - 专注于文本框不起作用

c# - 是否可以创建用于将项目添加到 Entity Framework dbset 的通用方法?

c# - EF5 代码优先 - 具有额外字段的多对多

entity-framework - 为什么 Entity Framework 5 在同一实体上执行 .ToList() 与 .Count() 时查询不同的表?

c# - 如何强制读取和写入位于 C :\? 中的文件

c# - 为什么在 Controller 上设置了 SessionStateBehavior.ReadOnly 后我仍然可以写入 session ,我应该关心吗?

c# - MVC4 bundle 返回 404

c# - 如何动态覆盖 Html.ActionLink 生成的 URL?