EF自动迁移不适用于虚拟财产

时间:2012-06-13 08:38:08

标签: entity-framework-4 ef-code-first sql-server-ce database-migration entity-framework-4.3

我首先尝试使用实体框架和代码进行自动迁移。我向我的班级添加了新属性(团队也是自定义类):

public virtual Team SecondTeam { get; set; }

我有更新数据库的问题。在我写命令后,我在控制台中得到了这个:

  

SQL Server Compact不支持直接列重命名。至   重命名SQL Server Compact中的列,您需要重新创建它。

通常正在更新工作(我试图添加简单的int prop,它只是更新)但我有问题,如果它是虚拟的。谁能帮我这个? 谢谢

修改:Update-Database -Verbose

之后的所有行
Using NuGet project 'Project'.  
Using StartUp project 'Project'.  
Target database is: '|DataDirectory|database.sdf' (DataSource: |DataDirectory|database.sdf, Provider: System.Data.SqlServerCe.4.0, Origin: Configuration). 
No pending explicit migrations. 
Applying automatic migration: 201206130828142_AutomaticMigration. 
Direct column renaming is not supported by SQL Server Compact. To rename a column in SQL Server Compact, you will need to recreate it.

EDIT2: 我想要更改数据库的Player类:

public class Player
    {
        [Key]
        public int PlayerID { get; set; }

        [Required]
        public string Name { get; set; }
        [Required]
        public string Surname { get; set; }
        public string Nickname { get; set; }
        public DateTime Birth { get; set; }

        public string PhotoUrl { get; set; }
        public string Post { get; set; }

        public int TeamID { get; set; }
        public virtual Team Team { get; set; }

        public int SecondTeamID { get; set; }
        public virtual Team SecondTeam { get; set; }

        public int UserId { get; set; }
        public virtual User User { get; set; }
    }

团队课程:

public class Team
    {
        [Key]
        public int TeamID { get; set; }
        public string Name { get; set; }

        public string League { get; set; }
        public string Trainings { get; set; }

        public string PhotoUrl { get; set; }

        public int CoachID { get; set; }
        public int AassistantID { get; set; }
        public int ManagerID { get; set; }

        public virtual ICollection<Player> Players { get; set; }

        public bool showPosts { get; set; }
    }

这是由EF生成的SQL:

CREATE TABLE "Players" (
    "PlayerID" int not null identity,
    "Name" nvarchar(4000) not null,
    "Surname" nvarchar(4000) not null,
    "Nickname" nvarchar(4000) null,
    "Birth" datetime not null,
    "PhotoUrl" nvarchar(4000) null,
    "Post" nvarchar(4000) null,
    "TeamID" int not null,
    "SecondTeamID" int not null,
    "UserId" int not null,
    "Team_TeamID" int null,
    "Team_TeamID1" int null,
    "SecondTeam_TeamID" int null,
    PRIMARY KEY ("PlayerID")
);

ALTER TABLE "Players" ADD CONSTRAINT "Team_Players" FOREIGN KEY ("Team_TeamID") REFERENCES "Teams"("TeamID");
ALTER TABLE "Players" ADD CONSTRAINT "Player_Team" FOREIGN KEY ("Team_TeamID1") REFERENCES "Teams"("TeamID");
ALTER TABLE "Players" ADD CONSTRAINT "Player_SecondTeam" FOREIGN KEY ("SecondTeam_TeamID") REFERENCES "Teams"("TeamID");
ALTER TABLE "Players" ADD CONSTRAINT "Player_User" FOREIGN KEY ("UserId") REFERENCES "Users"("UserID") ON DELETE CASCADE;

2 个答案:

答案 0 :(得分:2)

我知道这是一个老问题,但我认为解决方案以后会有用。

除非您确定代码仅限于调试环境,否则请勿使用RecreateDatabaseIfModelChanges功能。如果它在生产代码中滑动(并且您可能并不总是在发布之前查看DAL),意外的数据丢失很容易成为问题。

如果您正确使用迁移,您将看到EF为您生成如下代码:

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

    public partial class TargetInventoryChange : DbMigration
    {
        public override void Up()
        {
            RenameColumn(table: "dbo.TargetInventoryItems", name: "MatchedPrinter_ID", newName: "MatchedPrinterID");
            AddColumn("dbo.TargetInventoryItems", "CustomerID", c => c.String(maxLength: 40));
            AlterColumn("dbo.TargetInventoryItems", "Name", c => c.String(maxLength: 100));
        }

        public override void Down()
        {
            AlterColumn("dbo.TargetInventoryItems", "Name", c => c.String(maxLength: 4000));
            DropColumn("dbo.TargetInventoryItems", "CustomerID");
            RenameColumn(table: "dbo.TargetInventoryItems", name: "MatchedPrinterID", newName: "MatchedPrinter_ID");
        }
    }
}

在这个特定项目中,我保留了两组迁移,一组用于SQL CE数据库,另一组用于SQL Server。在为Compact版本进行迁移时,我偶然发现了你的问题。

我只是按照错误信息说的解决了这个问题。 请注意,这会导致您重命名的列上的数据丢失。请注意。

这个例子解决了外键情况,这是(我相信)最糟糕的情况之一,因为EF自己生成列,FK约束和自动索引。

public override void Up()
{
    //RenameColumn(table: "dbo.TargetInventoryItems", name: "MatchedPrinter_ID", newName: "MatchedPrinterID");
    DropIndex("dbo.TargetInventoryItems", "IX_MatchedPrinter_ID");
    DropForeignKey("dbo.TargetInventoryItems", "FK_dbo.TargetInventoryItems_dbo.CustPrinters_MatchedPrinter_ID");
    DropColumn("dbo.TargetInventoryItems", "MatchedPrinter_ID");
    AddColumn("dbo.TargetInventoryItems", "MatchedPrinterID", c => c.Int());
    AddForeignKey("dbo.TargetInventoryItems", "MatchedPrinterID", "dbo.CustPrinters", "ID");
    CreateIndex("dbo.TargetInventoryItems", "MatchedPrinterID", unique: false);
}

如果您不知道索引的名称,可以使用SQL CE工具箱(http://sqlcetoolbox.codeplex.com/)查看特定表。您将看到一个索引列表,您可以在其中找到要删除的名称。

对于FK约束,您必须查询INFORMATION_SCHEMA,例如再次使用SQL CE Toolbox,使用类似

的查询
SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS

根据需要添加一些WHERE条件。我希望这将在适当的SQL生成器上修复,但同时这实际上解决了问题 - 对于小的更改。

答案 1 :(得分:0)

我认为如果您按照此示例Steven Sanderson - MvcScaffolding: One-to-Many Relationships进行开发,并在开发期间使用该功能根据Scott Guthrie - Code-First Development with Entity Framework 4博客在启动时重新创建数据库。 (搜索段落Taking advantage of SQL CE 4The RecreateDatabaseIfModelChanges Feature