Невозможно вставить в таблицу отношений «многие ко многим» без дублирования записей - PullRequest
0 голосов
/ 07 марта 2019

У меня есть следующие объекты: Большинство свойств удалено.

public class WorkQueue : IEntity
{
    public WorkQueue()
    {

    }

    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public virtual ICollection<Action> Actions { get; set; }
    public virtual ICollection<Role> AllowableRoles { get; set; }
}

public class Role: IEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public virtual ICollection<Action> Actions { get; set; }
    public virtual ICollection<WorkQueue> AllowedWorkQueues { get; set; }
}

public class Action: IEntity
{
    public Action()
    {
        Roles = new HashSet<Role>();
    }

    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
    public string Name { get; set; }


    public virtual Guid WorkQueue_Id { get; set; }
    public virtual WorkQueue WorkQueue { get; set; }

    public virtual ICollection<Role> Roles { get; set; }
}

И следующие конфигурации типов сущностей:

public class WorkQueueConfig : EntityTypeConfiguration<WorkQueue>
{
    public WorkQueueConfig()
    {
        HasMany(x => x.AllowableRoles)
            .WithMany(x => x.AllowedWorkQueues)
            .Map(m =>
            {
                m.MapLeftKey("WorkQueueId");
                m.MapRightKey("RoleId");
                m.ToTable("AllowableRolesByWorkQueue");
            });

        HasMany(x => x.Actions)
            .WithRequired(x => x.WorkQueue)
            .WillCascadeOnDelete(false);
    }
}

public class ActionConfig: EntityTypeConfiguration<Action>
{
    public ActionConfig()
    {
        HasMany(x => x.Roles)
            .WithMany(x => x.Actions)
            .Map(m =>
            {
                m.MapLeftKey("ActionId");
                m.MapRightKey("RoleId");
                m.ToTable("ActionRole");
            });

        HasRequired(x => x.WorkQueue)
            .WithMany(x => x.Actions)
            .WillCascadeOnDelete(false);
    }
}

Что приводит к следующему, что меня устраивает:

enter image description here

Проблема в том, что когда я пытаюсь вставить новую WorkQueue, мои Role записи в базе данных дублируются.Я уже вставил все возможные Role сущности.

Я прочитал несколько решений, но, похоже, ни одно из них не работает для меня.Я пробовал следующее:

Отправка только идентификаторов ролей в БД.Это не сработало.

private async Task<WorkQueue> SetRolesAsPerContext(WorkQueue workQueue)
    {
        if (workQueue.AllowableRoles != null && workQueue.AllowableRoles.Count > 0)
        {
            ICollection<Role> roles = await _repository.GetAllAsync<Role>();
            IEnumerable<Guid> selectedRoleIds = workQueue.AllowableRoles.Select(s => s.Id);
            var filteredRoles = roles.Where(r => selectedRoleIds.Contains(r.Id))
                .Select(r => new Role() { Id = r.Id })
                .ToList();

            //set workqueue roles
            workQueue.AllowableRoles = filteredRoles;

            if (workQueue.Actions != null && workQueue.Actions.Count > 0)
            {
                foreach (SimO2O.Models.Action action in workQueue.Actions)
                {
                    IEnumerable<Guid> selectedActionRoleIds = action.Roles.Select(s => s.Id);
                    action.Roles = roles.Where(r => selectedActionRoleIds
                        .Contains(r.Id))
                        .Select(r => new Role() { Id = r.Id })
                        .ToList();
                }
            }
        }

        return workQueue;
    }

Я также пытался присоединить объекты Role к текущему контексту, чтобы EntityFramework не видел их как новые объекты, и, наконец, попытался установить для EntityState значениеDetached, но это продолжает создавать дубликаты ролей.

public async Task<Guid> CreateWorkQueueAsync(WorkQueue workQueue, string userName)
    {
        //set Permissions on same context
        _repository.AttachEntity(workQueue.AllowableRoles);
        _repository.ModifyState(workQueue.AllowableRoles, System.Data.Entity.EntityState.Detached);

        _repository.Create(workQueue, workQueue.AllowableRoles, userName);
        await _repository.SaveAsync();
        return workQueue.Id;
    }

Ниже приведены методы, которые я написал в классе _repository для присоединения и установки EntityState.

public void AttachEntity<TEntity>(TEntity entity) where TEntity : class, IEntity
    {
        Context.Set<TEntity>().Attach(entity);
    }

    public void AttachEntity<TEntity>(ICollection<TEntity> entities) where TEntity : class, IEntity
    {
        foreach (TEntity entity in entities)
            Context.Set<TEntity>().Attach(entity);
    }

    public void ModifyState<TEntity>(TEntity entity, EntityState state) where TEntity : class, IEntity
    {
        Context.Entry(entity).State = state;
    }

    public void ModifyState<TEntity>(ICollection<TEntity> entities, EntityState state) where TEntity : class, IEntity
    {
        foreach (TEntity entity in entities)
            Context.Entry(entity).State = state;
    }
* 1034.* Чего мне здесь не хватает?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...