InvalidOperationException: экземпляр объекта не может быть отслежен - EF Core - PullRequest
0 голосов
/ 11 июня 2019

Я пытаюсь сохранить дату в нескольких таблицах с отношением один ко многим при использовании EF Core.Когда я это получаю, я получаю эту ошибку:

InvalidOperationException: экземпляр типа сущности 'OrganizationGroupEntity' не может быть отслежен, поскольку другой экземпляр с таким же значением ключа для {'Id'} уже отслеживается.При подключении существующих объектов убедитесь, что подключен только один экземпляр объекта с данным значением ключа.Подумайте об использовании DbContextOptionsBuilder.EnableSensitiveDataLogging для просмотра конфликтующих значений ключа.

Вот мой код:

Модель запроса:

public class Organization
{
    public Organization()
    { }

    public Organization(OrganizationEntity organizationEntity, List<OrganizationGroupEntity> organizationGroupEntities)
    {
        Id = organizationEntity.Id;
        Name = organizationEntity.Name;
        Groups = ToList(organizationGroupEntities);
    }

    public int Id { get; set; }
    public string Name { get; set; }}
    public List<OrganizationGroup> Groups { get; set; }

    private List<OrganizationGroup> ToList(List<OrganizationGroupEntity> organizationGroupEntities)
    {
        return organizationGroupEntities.Select(
                entity => new OrganizationGroup(entity)
            ).ToList();
    }
}

public class OrganizationGroup
{
    public OrganizationGroup()
    { }

    public OrganizationGroup (OrganizationGroupEntity entity)
    {
        Id = entity.Id;
        Group = entity.Group;
    }

    public int Id { get; set; }
    public string Group { get; set; }
}

Модели сущностей:

public class OrganizationEntity
{
    public OrganizationEntity()
    { }

    public OrganizationEntity(Organization model)
    {
        Id = model.Id;
        Name = model.Name;
    }

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

public class OrganizationGroupEntity
{
    public OrganizationGroupEntity()
    { }

    public OrganizationGroupEntity(int organizationId, OrganizationGroup model)
    {
        Id = model.Id;
        OrganizationId = organizationId;
        Group = model.Group;
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public int OrganizationId { get; set; }
    public string Group { get; set; }
}

dbContext:

public DbSet<OrganizationEntity> Organizations { get; set; }
public DbSet<OrganizationGroupEntity> OrganizationGroups { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<OrganizationEntity>()
        .ToTable("Organizations", "dbo");

    modelBuilder.Entity<OrganizationGroupEntity>()
        .ToTable("OrganizationGroups", "dbo");
}

хранилище:

public async Task<Organization> UpdateOrganization(Organization request)
{
    // Get the org entity
    var organizationEntity = new OrganizationEntity(request);

    // get the org groups entities
    var groupEntities = request.Groups
        .Select(
            group => new OrganizationGroupEntity(request.Id, group)
        ).ToList();

    // Get the group entities to remove
    var oldEntities = GetOrganizationGroups(request.Id);
    var entitiesToRemove = new List<OrganizationGroupEntity>();
    foreach (var oldEntity in oldEntities.Result)
    {
        if (!groupEntities.Any(e => e.Id == oldEntity.Id))
        {
            entitiesToRemove.Add(oldEntity);
        }
    }

    using (var transaction = _context.Database.BeginTransaction())
    {
        _context.Organizations.Update(organizationEntity);
        _context.OrganizationGroups.UpdateRange(groupEntities);        // <-- Fails here
        _context.OrganizationGroups.RemoveRange(entitiesToRemove);
        await _context.SaveChangesAsync();
        transaction.Commit();
    }

    return request;
}

private async Task<IEnumerable<OrganizationGroupEntity>> GetOrganizationGroups(int organizationId)
{
    return await _context.OrganizationGroups
        .Where(e => e.OrganizationId == organizationId)
        .OrderBy(e => e.Order)
        .ToListAsync();
}

1 Ответ

0 голосов
/ 11 июня 2019

Оказывается, когда я получал текущее значение groupEntities, чтобы определить, что нужно удалить, я инициировал отслеживание на этой таблице. Добавление AsNoTracking() к GetOrganizationGroups решило мою проблему. Вот так:

private async Task<IEnumerable<OrganizationGroupEntity>> GetOrganizationGroups(int organizationId)
{
    return await _context.OrganizationGroups
        .AsNoTracking()
        .Where(e => e.OrganizationId == organizationId)
        .OrderBy(e => e.Order)
       .ToListAsync();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...