Миграция кода неожиданно пытается переименовать таблицу


Я хочу реализовать журнал изменений, как это было рекомендовано в Dev Express XAF T474899

Я использую систему безопасности, созданную мастером XAF new solution wizard

Я определил некоторые бизнес-объекты для хранения информации журнала изменений.

Один из этих объектов хранит ссылку на пользователя

Публичный виртуальный пользователь User { get; set;}

При создании миграции кода я с удивлением вижу, что метод Up () добавляет следующее

RenameTable(name: "dbo.UserRoles", newName: "RoleUsers");
DropPrimaryKey("dbo.RoleUsers");
AddPrimaryKey("dbo.RoleUsers", new[] { "Role_ID", "User_ID" });

На другом случай я нашел следующий В Up ()

RenameTable(name: "dbo.EventResources", newName: "ResourceEvents");
// lots of other stuff
 DropPrimaryKey("dbo.ResourceEvents");
 AddPrimaryKey("dbo.ResourceEvents", new[] { "Resource_Key", "Event_ID" });
В обоих случаях код, создающий сущности, является библиотекой Dev Express libary.

Я уже отправил этот вопрос в Dev Express Support

Бизнес-объекты Dev Express определяются в DevExpress.Настойчивый.BaseImpl.EF;

Мой контекст DbContext ссылается на них как

public DbSet<Role> Roles { get; set; }
public DbSet<User> Users { get; set; }

Метаданные для ролевых шоу Введите описание изображения здесь

Метаданные для пользовательских шоу Введите описание изображения здесь

Мой собственные бизнес-классы содержат

    namespace SBD.JobTalk.Module.BusinessObjects
{
    [NavigationItem("Configuration")]
    [DisplayName("Staff")]
    [DefaultProperty("Summary")]
    [ImageName("BO_Employee")]
    [Table("Staff")]
    public class Staff : BasicBo
    {
        public Staff()
        {
            Person = new Person();
        }
        public virtual Person Person { get; set; }

        [StringLength(100, ErrorMessage = "The field cannot exceed 100 characters. ")]
        [scds.Index("IX_Staff_UserName", 1, IsUnique = true)]
        public string UserName { get; set; }
        [NotMapped]
        public string Summary => $"{Person.FirstName} {Person.LastName}";

        //public virtual User User { get; set; }
    }
}

public abstract class BasicBo : IXafEntityObject  
{
    [Browsable(false)]
    [Key]
    public virtual int Id { get; set; }
    public virtual void OnCreated()
    {

    }
      public virtual void OnSaving()
    {
    }

    public virtual void OnLoaded()
    {
    }
}

Если я откомментирую код, чтобы иметь свойство пользователя внутри Staff, и создам миграцию, миграция вверх будет

 public override void Up()
    {
        RenameTable(name: "dbo.UserRoles", newName: "RoleUsers");
        DropPrimaryKey("dbo.RoleUsers");
        AddColumn("dbo.Staff", "User_ID", c => c.Int());
        AddPrimaryKey("dbo.RoleUsers", new[] { "Role_ID", "User_ID" });
        CreateIndex("dbo.Staff", "User_ID");
        AddForeignKey("dbo.Staff", "User_ID", "dbo.Users", "ID");
    }

[обновить] Интересно, что существует больше таблиц Dev Express, чем я сначала думал. Первичные ключи-это идентичность.

Введите описание изображения здесь Я думаю, что использую стандартную аутентификацию, созданную до того, как Dev Express добавил возможность разрешить / запретить (V16. 1)

[обновить] Когда я создаю новый проект с указанными выше настройками, здесь это DbContext.

using System;
using System.Data;
using System.Linq;
using System.Data.Entity;
using System.Data.Common;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.ComponentModel;
using DevExpress.ExpressApp.EF.Updating;
using DevExpress.Persistent.BaseImpl.EF;
using DevExpress.Persistent.BaseImpl.EF.PermissionPolicy;

namespace XafApplication1.Module.BusinessObjects {
    public class XafApplication1DbContext : DbContext {
        public XafApplication1DbContext(String connectionString)
            : base(connectionString) {
        }
        public XafApplication1DbContext(DbConnection connection)
            : base(connection, false) {
        }
        public XafApplication1DbContext()
            : base("name=ConnectionString") {
        }
        public DbSet<ModuleInfo> ModulesInfo { get; set; }
        public DbSet<PermissionPolicyRole> Roles { get; set; }
        public DbSet<PermissionPolicyTypePermissionObject> TypePermissionObjects { get; set; }
        public DbSet<PermissionPolicyUser> Users { get; set; }
        public DbSet<ModelDifference> ModelDifferences { get; set; }
        public DbSet<ModelDifferenceAspect> ModelDifferenceAspects { get; set; }
    }
}
1 2

1 ответ:

Хорошо, я возьму удар :) ваш код Up () пытается переименовать таблицу UserRoles в RoleUsers. Это означает, что у вас есть предыдущая миграция, где UserRoles было имя таблицы - вероятно, из вашего материала DevEx. Это может произойти, если они изменят свои модели в процессе обновления. Нынешние модели ожидают ролевиков и т. д. так что тебе нужно туда попасть.

Итак, первый вариант-позволить миграции сделать переименование, чтобы соответствовать базовой модели. Я предполагаю, что это не сработало или вызывает другие проблемы?

Вы можете "обмануть" entity framework, используя старые таблицы с плавным кодом или аннотациями, но если у него есть новые столбцы или связи, которые не будут работать.

Я бы сделал вот что:

1) Создайте новый тестовый проект с теми же ссылками, которые у вас были, и скопируйте контекст и наборы баз данных. Указать строку подключения к новая база данных.

2) Добавьте миграцию и запишите ее: update-database -Script.

3) изучите этот скрипт и используйте его для создания то объекты, необходимые в вашей базе данных. Перенос данных из старого таблицы к новым, если это необходимо.

4) Удалите старые таблицы

[3]}5) в вашем фактическом проект добавление миграции для повторной синхронизации моделей: add-migration SyncDevExUpdate -IgnoreChange, update-database

Теперь у вас будут таблицы, которые ожидают ваши модели.