2016-07-26 2 views
3

내가 여기 설명서를 따랐습니다 시행되고, 나는 다음 SQL 서버 2016 내가 VersionCol라는 이름의 내 테이블에 타임 스탬프 열을 추가 한 (https://ef.readthedocs.io/en/latest/modeling/concurrency.html)EF 코어 동시성은

를 사용하고있어하지 않을 경우 I Scaffold-DbContext를 실행하면 내 DbContext의 내 테이블 엔터티에 다음 속성을 배치합니다. 그것은 .IsConcurrencyToken()을 실종

entity.Property(e => e.VersionCol) 
    .IsRequired() 
    .HasColumnType("timestamp") 
    .ValueGeneratedOnAddOrUpdate() 

그래서 나는 나 자신에 있지만, 여전히 예외가 동시성 문제를 고통을해야 상황에서 발생하지 않습니다 것을 추가했습니다. 대신 단순히 데이터를 덮어 씁니다.

누락 된 것이 있습니까?

편집 :

나는 데이터베이스 - 첫 번째 방법 (그래서 아무 [타임 스탬프] 또는 다른 주석)을 사용하고, 내 DbContext가 Startup.cs

services.AddScoped<IPoRepository, PoRepository>()로 구성, 서비스에 주입되고

내 모델에 public byte[] VersionCol { get; set; } 필드가 생성됩니다. 내 PoRepository에서

나는 다음 내 포를 업데이트하기 위해 노력하고있어 : 그것은 단지 그것의 일부가되도록

public void SavePo(PoListing poListing) { 
    Po po; 

    try { 
     po = _context.Po.Where(p => p.Poid == poListing.PoId).First(); 
    } catch (ArgumentNullException) { 
     throw new ArgumentNullException("The PO does not exist."); 
    } 

    po.AssignedUserId = poListing.AssignedUserId; 
    po.VersionCol  = poListing.VersionCol; 

    _context.Entry(po).State = EntityState.Modified; 

    _context.SaveChanges(); 
} 

PoListing 본질적으로 포의 단지 부분 열 (이 테이블 아니다이다 데이터베이스에 있음), 처음 생성 될 때 Po의 VersionCol을가집니다. PoListing이 PoC보다 이전 버전의 VersionCol을 가지고 있다면 예외가 발생합니다.

Edit2가 :

이 작동하지만, 나는 그것이이 두 번째 문맥을 할 필요없이 작동하도록, 그냥 주입 컨텍스트를 사용하는 방법을 알아낼 수 없습니다.

public void SavePo(PoListing poListing) { 
    DbContextOptionsBuilder<TMS_1000Context> options = new DbContextOptionsBuilder<TMS_1000Context>(); 
    options.UseSqlServer("Server=DEVSQL16;Database=TMS_1000_Dev;Trusted_Connection=True;MultipleActiveResultSets=true"); 

    TMS_1000Context context1; 

    try { 
     po = _context.Po.Where(p => p.Poid == poListing.PoId).First(); 
    } catch (ArgumentNullException) { 
     throw new ArgumentNullException("The PO does not exist."); 
    } 

    using (context1 = new TMS_1000Context(options.Options)) { 
     po.AssignedUserId = poListing.AssignedUserId; 
     po.VersionCol = poListing.VersionCol; 

     context1.Update(po); 

     context1.SaveChanges(); 
    } 
} 

EDIT3 :

이 현재 작동하고

. 다른 방법이 있습니까? EF 코어 추적이 원래 값이 데이터베이스에 현재의 것과 동일한 경우에만 고려하고 그들이 다음하지 않은 경우 동시성 예외가 발생 될 때이기 때문에

public void SavePo(PoListing poListing) { 
    Po po; 

    try { 
     po = _context.Po.Where(p => p.Poid == poListing.PoId).First(); 
    } catch (ArgumentNullException) { 
     throw new ArgumentNullException("The PO does not exist."); 
    } 

    po.AssignedUserId = poListing.AssignedUserId; 

    _context.Entry(po).Property(u => u.VersionCol).OriginalValue = poListing.VersionCol; 

    _context.Update(po); 
    _context.SaveChanges(); 
} 
+1

당신은, 데이터 컨텍스트에 전달 나는 당신이 당신의 개체를 업데이트 할 방법을 찾으시는 것을 우리에게 보여 주시겠습니까와 같은 유사 기능? –

+1

추가 정보를 추가 할 수 있습니까? 코드 우선 모델이나 DbContext의'OnModelCreating' 메소드에'[Timestamp]'속성을 추가 하시겠습니까? 아니면 기존 데이터베이스에서 스캐 폴드 한 데이터베이스 우선 접근 방법을 시도하고 있습니까? 모델 및 DbContext 코드를 적어도 관련 OnModelCreating에 게시하십시오. – Tseng

+0

자세한 내용을 추가했습니다.보고 싶은 것이 있으면 알려 주시기 바랍니다. – GlacialFlames

답변

0

나는 이런 일이 믿는 이유입니다.

다음은 내가 발견 한 3 가지 수정 사항입니다.

  1. 원래 값을 데이터베이스에있는 것과 다른 값으로 변경하십시오.

    public void SavePo(PoListing poListing) { 
        Po po; 
    
        try { 
         po = _context.Po.Where(p => p.Poid == poListing.PoId).First(); 
        } catch (ArgumentNullException) { 
         throw new ArgumentNullException("The PO does not exist."); 
        } 
    
        po.AssignedUserId = poListing.AssignedUserId; 
    
        _context.Entry(po).Property(u => u.VersionCol).OriginalValue = poListing.VersionCol; 
    
        _context.Update(po); 
        _context.SaveChanges(); 
    } 
    
  2. 이 AsNoTracking와 개체를 가져옵니다(). 이제 EF Core는 원래 값을 비교하지 않습니다.

    public void SavePo(PoListing poListing) { 
        Po po; 
    
        try { 
         po = _context.Po.AsNoTracking().Where(p => p.Poid == poListing.PoId).First(); 
        } catch (ArgumentNullException) { 
         throw new ArgumentNullException("The PO does not exist."); 
        } 
    
        po.AssignedUserId = poListing.AssignedUserId; 
        po.VersionCol  = poListing.VersionCol; 
    
        _context.Update(po); 
        _context.SaveChanges(); 
    } 
    
  3. 컨텍스트에서 엔티티를 분리합니다.수정 # 2

    public void SavePo(PoListing poListing) { 
        Po po; 
    
        try { 
         po = _context.Po.Where(p => p.Poid == poListing.PoId).First(); 
        } catch (ArgumentNullException) { 
         throw new ArgumentNullException("The PO does not exist."); 
        } 
    
        po.AssignedUserId = poListing.AssignedUserId; 
        po.VersionCol  = poListing.VersionCol; 
    
        _context.Entry(po).State = EntityState.Detached; 
    
        _context.Update(po); 
        _context.SaveChanges(); 
    } 
    
관련 문제