ASP.NET Core 3.1. 컬렉션 업데이트 문제
ASP.NET Core의 애플리케이션을 2.1에서 3.1로 마이그레이션하고 Entity Framework에 문제가 있습니다.
GlassesLenses
컬렉션 이있는 엔터티가 있습니다.
public class GlassesContract : BaseUpdateEntity, IAggregateRoot
{
public Guid Id { get; private set; } = Guid.NewGuid();
private readonly List<GlassesLenses> _glassesLenses = new List<GlassesLenses>();
public ICollection<GlassesLenses> GlassesLenses => _glassesLenses.AsReadOnly().ToList();
public void ClearLenses()
{
_glassesLenses.RemoveRange(0, _glassesLenses.Count);
}
public void AddLens(GlassesLenses lens)
{
_glassesLenses.Add(lens);
}
}
렌즈 업데이트 서비스 :
public async Task<GlassesContract> ChangeSetting(GlassesContract contract)
{
// clean lenses
contract.ClearLenses();
await _glassesContractRepository.UpdateAsync(contract);
// add new lens
contract.AddLens(new GlassesLenses());
await _glassesContractRepository.UpdateAsync(contract);
return contract;
}
버전 2.1에서는 동작이 잘 작동합니다. 컬렉션이 지워지고 (EF는 삭제를 위해 엔티티를 표시 함) 삽입을위한 새 엔티티로 새 렌즈 EF 마크를 추가 한 후
버전 3.1에서는 삭제 및 삽입 대신 EF Core가 업데이트 만 수행합니다.
// delete lens
UPDATE public."GlassesContracts"
SET "AccountId" = @p0, "BalancePaymentDeposit" = @p1, ...
WHERE "Id" = @p42 AND "SysRowVer" IS NULL
RETURNING "SysRowVer";
// add new lens
UPDATE public."GlassesContracts"
SET "AccountId" = @p0, "BalancePaymentDeposit" = @p1, ...
WHERE "Id" = @p42 AND "SysRowVer" IS NULL
RETURNING "SysRowVer";
UPDATE public."GlassesLenses"
SET "Availability" = @p43, "Color" = @p44, ...
WHERE "Id" = @p77 AND "SysRowVer" IS NULL
RETURNING "SysRowVer";
DbContext 매핑 :
// mapping relationship
modelBuilder.Entity<GlassesContract>()
.HasMany(_ => _.GlassesLenses)
.WithOne(_ => _.GlassesContract)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GlassesLenses>()
.HasOne(_ => _.GlassesContract)
.WithMany(_ => _.GlassesLenses);
// mapping Value objects
modelBuilder.Entity<GlassesLenses>().OwnsOne(o => o.Price).WithOwner();
modelBuilder.Entity<GlassesLenses>().OwnsOne(o => o.PriceExclVat).WithOwner();
modelBuilder.Entity<GlassesLenses>().OwnsOne(o => o.FinalPrice).WithOwner();
modelBuilder.Entity<GlassesLenses>().OwnsOne(o => o.FinalPriceExclVat).WithOwner();
modelBuilder.Entity<GlassesLenses>().OwnsOne(o => o.Discount).WithOwner();
엔티티를 AddAsync(entity)
또는로 표시하면 Remove(entity)
올바른 SQL이 INSERT 및 DELETE로 생성됩니다.
새 버전 3.1이 v2.1만큼 똑똑하지 않은 이유와 SysRowVer
(동시성 토큰)이 항상 NULL이고 업데이트되지 않는 이유를 설명 할 수 있습니까 ?
정말 고맙습니다
최신 정보
엔터티 추적기는 AddLens (..) 호출 후 '엔티티 GlassesLens가 수정 됨'이라고 말합니다. 왜 새로운 것으로 추가되었는지 이해할 수 없습니다.
--- 해결 ----
답변
EF 데이터베이스 컨텍스트 테이블 매핑 사용
modelBuilder.Entity<GlassesContract >(m =>
{
m.OwnsMany(i => i.GlassesLenses); //instead of HasMany().WithOne()
});
OwnsMany에 대한 자세한 설명은이 SO를 확인하십시오.
해결책을 찾았습니다 (내 지식 실수). 문제는 EF Core 3+의 주요 변경 사항입니다.
GUID를 기본 키로 사용하고 있습니다. DDD 규칙 및 엔티티 프레임 워크를 사용하는 애플리케이션이이 동작을 변경했기 때문에 이는 생성 된 값이 아닙니다.
DatabaseGenerated
속성 추가로 ID가 생성되지 않았 음을 EF에 알려야 합니다.
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; private set; } = Guid.NewGuid();
또는 DbContext에 능통
modelBuilder
.Entity<GlassesLenses>()
.Property(e => e.Id)
.ValueGeneratedNever();
신의 축복 이 게시물
그리고 원본은
DetectChanges는 저장소 생성 키 값을 준수합니다.
모두 감사합니다