Обновление EF Core с отслеживаемыми объектами - PullRequest
1 голос
/ 01 ноября 2019

Я использую ABP Framework, и я действительно борюсь с проблемой обновления. Я использую сущность frmaework core.

Я постараюсь сделать все как можно яснее.

У меня есть таблица категорий, в которой содержатся имена категорий и сведения о категории.

Затем я создаю угловой пользовательский интерфейс, который позволяет выбирать категории и сохранять их в объекте выполнения.

Затем моя цель состоит в том, чтобы хранить Accomplishement и категории.

Затем я создал таблицу AccomplishementCategoryCustoms.

Итак, моя модель выглядит следующим образом:

[Table("Accomplishments")]
public class Accomplishment : AuditedEntity 
{

    [Required]
    public virtual string Name { get; set; }

   public List<AccomplishementCategoryCustom> Categories { get; set; }
}

[Table("AccomplishementCategoryCustoms")]
public class AccomplishementCategoryCustom : CreationAuditedEntity 
{


    public virtual int? CategoryId { get; set; }

    [ForeignKey("CategoryId")]
    public Category CategoryFk { get; set; }

    public virtual int? AccomplishmentId { get; set; }

    [ForeignKey("AccomplishmentId")]
    public Accomplishment AccomplishmentFk { get; set; }

}

У меня нет отношений между категориями и AccomplishementCategoryCustoms.

Тогда, когда я вставляю, она работает хорошо.

Когда я обновляю и добавляю включение, у меня появляется ошибка, как показано ниже:

With include

Когда я обновляю без включения, у меня появляется ошибка:

Microsoft.EntityFrameworkCore.DbUpdateException: при обновлении записей произошла ошибка. Смотрите внутреннее исключение для деталей. ---> System.Data.SqlClient.SqlException: Невозможно вставить явное значение для столбца идентификаторов в таблице 'AccomplishementCategoryCustoms', когда для IDENTITY_INSERT задано значение OFF.

В конечном итоге построитель модели выглядит следующим образом:

 migrationBuilder.CreateTable(
            name: "AccomplishementCategoryCustoms",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                CreationTime = table.Column<DateTime>(nullable: false),
                CreatorUserId = table.Column<long>(nullable: true),
                CategoryId = table.Column<int>(nullable: true),
                AccomplishmentId = table.Column<int>(nullable: true)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_AccomplishementCategoryCustoms", x => x.Id);
                table.ForeignKey(
                    name: "FK_AccomplishementCategoryCustoms_Accomplishments_AccomplishmentId",
                    column: x => x.AccomplishmentId,
                    principalTable: "Accomplishments",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Restrict);
                table.ForeignKey(
                    name: "FK_AccomplishementCategoryCustoms_Categories_CategoryId",
                    column: x => x.CategoryId,
                    principalTable: "Categories",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Restrict);
            });

        migrationBuilder.CreateIndex(
            name: "IX_AccomplishementCategoryCustoms_AccomplishmentId",
            table: "AccomplishementCategoryCustoms",
            column: "AccomplishmentId");

        migrationBuilder.CreateIndex(
            name: "IX_AccomplishementCategoryCustoms_CategoryId",
            table: "AccomplishementCategoryCustoms",
            column: "CategoryId");
    }

Надеюсь, это будет достаточно подробно, чтобы исправить это, потому что я долго боролся с этим и не могу разобраться.

Ответы [ 2 ]

0 голосов
/ 01 ноября 2019

Исходя из вашего ответа, предполагая, что _dbContextProvider.GetDbContext(Abp.MultiTenancy.MultiTenancySides.Host) возвращает целевой контекст базы данных, на который я пришел выводить из вашего ответа, вы можете использовать следующий код, чтобы сохранить изменения в достижении, включая добавление или удаление категорий, при условии, чточто ObjectMapper.Map(input, accomplishment) - это то, что вносит изменения в достижение, полученное из хранилища, используя входные данные, также предполагая, что ObjectMapper.Map(input, accomplishment) возвращает тип объекта.

async Task Update(CreateOrEditAccomplishmentsDto input)
{
    var context = _dbContextProvider.GetDbContext(Abp.MultiTenancy.MultiTenancySides.Host);
    context.Entry(ObjectMapper.Map(input, _accomplishmentRepository.GetAll().Where(a => a.Id == input.Id.Value).Include(a => a.Categories).FirstOrDefault())).State = EntityState.Modified;
    await context.SaveChangesAsync();
}

Технически, часть context.Entry(...).State = EntityState.Modified этогострока избыточна, но я не уверен в реализации всего, что вы предоставили, поэтому я учитываю контекст, который фактически не отслеживает возвращаемый объект от вызова к Map.

Если выполучают исключение из-за того, что контекст уже отслеживает сущность с таким же значением для id, затем удаляет следующую строку.

context.Entry(ObjectMapper.Map(input, _accomplishmentRepository.GetAll().Where(a => a.Id == input.Id.Value).Include(a => a.Categories).FirstOrDefault())).State = EntityState.Modified;

Затем добавьте следующую строку вместо перед звонком на SaveChangesAsync.

ObjectMapper.Map(input, _accomplishmentRepository.GetAll().Where(a => a.Id == input.Id.Value).Include(a => a.Categories).FirstOrDefault());
0 голосов
/ 01 ноября 2019

Хорошо, поэтому я попытался с помощью следующего кода:

  var accomplishment = _accomplishmentRepository.GetAll().AsNoTracking().Where(a => 
  a.Id ==input.Id.Value)
  .Include(a => a.Categories)
  .FirstOrDefault();

  var updatedEntity =  ObjectMapper.Map(input, accomplishment);

   await _accomplishmentRepository.UpdateAsync(updatedEntity);

У меня больше нет ошибки. Это хорошо обновлено.

Однако, если я отменяю выбор одной категории в моем пользовательском интерфейсе и обновляю, строка в БД должна быть удалена.

К сожалению, изменение не отражено в базе данных. Строка не меняется.

Затем я попытался присоединить и настроить измененный, но у меня есть ошибка ниже:

enter image description here

Какя могу решить эту проблему?

Я действительно не понимаю, как я могу решить это.

...