1

Сначала я пытаюсь использовать автоматическую миграцию с сущностью и кодом. Я добавил новое свойство в свой класс (Team также является обычным классом):EF Автоматическая миграция, не работающая с виртуальной собственностью

У меня проблема с обновлением базы данных. После того, как я пишу команду, я получаю это в своей консоли:

Прямое переименование столбцов не поддерживается SQL Server Compact. В переименуйте столбец в SQL Server Compact, вам нужно будет его воссоздать.

Обычно обновляется работа (я попытался добавить простой int prop, и он просто обновляется), но у меня проблема, если это виртуально. Кто-нибудь может мне с этим помочь? Спасибо

Edit: Все строки после 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: класса игрока, где я хочу, чтобы изменить базу данных:

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; } 
    } 

И это SQL, сгенерированный EF:

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; 
+0

Запустите 'Update-Database -Script', чтобы увидеть, что он пытается переименовать, или воспользуйтесь опцией' -Verbose', чтобы узнать больше. – Richard

+0

Я попробовал, но мне это не помогло. –

+0

Отправьте сгенерированный SQL и весь код вашего объекта в свой вопрос. Похоже, что EF думает, что вы переименовали свойство вместо добавления нового свойства. –

ответ

0

Я думаю, что если вы будете следовать этому образцу Steven Sanderson - MvcScaffolding: One-to-Many Relationships и во время разработки использовать функцию, чтобы воссоздать базу данных при запуске согласно Scott Guthrie - Code-First Development with Entity Framework 4 блоге. (Поиск абзаца Taking advantage of SQL CE 4 и The RecreateDatabaseIfModelChanges Feature)

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. Во время производства миграции для компактного издания я наткнулся на вашу проблему.

Я решил, что это просто то, что говорится в сообщении об ошибке. Обратите внимание, что это приведет к потере данных в столбцах, которые вы переименовываете. Будьте осторожны.

В этом примере решается секретный ключ, который (я считаю) один из худших, поскольку 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 Toolbox (http://sqlcetoolbox.codeplex.com/). Вы увидите список индексов, где вы найдете имя для удаления.

Для ограничения FK вам необходимо запросить INFORMATION_SCHEMA, например. снова используя SQL CE Toolbox, с помощью запроса как

SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS 

Помещенный некоторые WHERE условия по мере необходимости. Я надеюсь, что это будет исправлено на соответствующем генераторе SQL, но в то же время это фактически решает проблему - для небольших изменений.

+0

Возможно, немой вопрос, но как вы поддерживаете второй набор миграций? – Josh

+1

С тех пор я перешел от этого проекта, но я помню, что у него что-то вроде пользовательского класса, установленного как DbConfiguration для контекста. В этом классе, в зависимости от некоторого значения конфигурации (в файле конфигурации XML моего приложения), я создавал экземпляр SQL CE или драйверов SQLSrv и строк подключения. Я просто запускал средства EF PowerShell для управления миграциями после обновления конфигурации и указания правильного каталога «Migrations» (/ namespace). То же самое для migrator: выберите правильный класс конфигурации из правильного пространства имен. –