0

내가 저장소 패턴을 사용하여 MVC 프로젝트를하고있는 중이 야 개체 및저장소 패턴 일반 쓰기 저장소 문제 - 상태 관리자 문제

public abstract class WriteRepository<TContext> : IWriteRepository 
    where TContext : DbContext, new() 
{ 
    private readonly TContext _context; 

    protected TContext Context { get { return _context; } } 

    protected WriteRepository() 
    { 
     _context = new TContext(); 
    } 

    public TItem Update<TItem>(TItem item, bool saveImmediately = true) where TItem : class, new() 
    { 
     return PerformAction(item, EntityState.Modified, saveImmediately); 
    } 

    public TItem Delete<TItem>(TItem item, bool saveImmediately = true) where TItem : class, new() 
    { 
     return PerformAction(item, EntityState.Deleted, saveImmediately); 
    } 

    public TItem Insert<TItem>(TItem item, bool saveImmediately = true) where TItem : class, new() 
    { 
     return PerformAction(item, EntityState.Added, saveImmediately); 
    } 

    public void Save() 
    { 
     _context.SaveChanges(); 
    } 

    protected virtual TItem PerformAction<TItem>(TItem item, EntityState entityState, bool saveImmediately = true) where TItem : class, new() 
    { 
     _context.Entry(item).State = entityState; 
     if (saveImmediately) 
     { 
      _context.SaveChanges(); 
     } 
     return item; 
    } 

    public void Dispose() 
    { 
     _context.Dispose(); 
    } 
} 

을 다음과 같이 내가 내 DB에 하나의 필드를 업데이트하고 싶었 핵심 쓰기 저장소가 내가하고 있었는데 작업 방법과 내가 좋아하는 그 값을 업데이트하기 전에 모든 것을 얻을 내가 동일한 키를 가진 개체가 이미 ObjectStateManager 존재 "라는 오류를 얻고 그렇게

public ActionResult UpdateTenant(string id) { Tenant model = new Tenant(); model = _TenantServices.GetItemById(Guid.Parse(id)); model.IsLoginEnabled = true; _TenantServices.Update(model); return RedirectToAction("ViewDetails", new { id = model.TenantId }); } 

아래 T 그는 ObjectStateManager 같은 키를 가진 여러 개체를 추적 할 수 없습니다. "

나는

public Tenant GetItemById(Guid id) 
{ 
      return Context.Tenants.AsNoTracking().Where(t => t.TenantId == id).FirstOrDefault(); 
} 

나는이 문제를 해결하는 방법에 어떤 아이디어를 다음과 같이 데이터를 검색 할 수 AsNoTracking을 사용하고?

+0

@HenkHolterman이 줄에 오류가 발생했습니다. _context.Entry (item) .State = entityState; 그냥 var 모델 = _TenantServices.GetItemById (Guid.Parse (id));에 할당해야합니다. ? – sani

+0

@HenkHolterman 제가 게시 한 코드에 아무런 문제가 없다고 언급했듯이, Tenant Repository 클래스에 문제가있었습니다. – sani

답변

1

데이터베이스에서 개체를 검색 할 때마다 개체가 즉시 추적 (첨부)됩니다. 검색된 개체 (예 : 속성 값 설정)를 변경하고 EntityState을 설정할 필요없이 개체가 데이터베이스에서 업데이트되도록 SaveChanges()으로 호출 할 수 있습니다.

Attach으로 시도하거나 이미 추적 된 개체의 EntityState을 설정하면 위에서 언급 한 오류가 발생합니다. 그래서

이 오류를 해결하기 위해, 당신은 할 수의의

  • 를 사용하여 하나 개의 인스턴스는 TContext 검색하는 또 다른 예를 업데이트 할 수 있습니다. 이 경우 변경 사항이 지속되도록 update 메소드에 EntityState을 첨부하고 설정해야합니다.
  • TContext의 단일 인스턴스를 사용하여 검색하고 업데이트하지만 Attach을 시도하거나 EntityState을 더 이상 설정하지 마십시오. 속성 값을 설정 한 후 바로 SaveChanges으로 전화하십시오.
  • TContext의 단일 인스턴스를 사용하지만 레코드를 검색 할 때는 AsNoTracking()을 호출 할 수 있습니다. 업데이트 도중 안전하게 Attach 또는 EntityState으로 설정할 수 있습니다.

희망이 있습니다.

+0

프로젝트에 여러 컨텍스트가있을 수 있습니까? 데이터 asnotracking을 검색하고 있지만 많은 효과가있는 것 같지 않습니다. – sani

+0

설명하는 문제는 'DbContext'에서 상속 한 클래스가 하나 뿐인 경우에도 발생할 수 있습니다. 그리고 여러 개의 컨텍스트 클래스가 있더라도 세입자의 DbSet을 보유하는 컨텍스트 클래스가 하나만 있다고 믿습니다 (확인하십시오). –

+0

그래, 단 하나의 dbcontext가있다 – sani