IT Share you

동일한 키를 가진 개체가 ObjectStateManager에 이미 있습니다.

shareyou 2020. 12. 6. 22:18
반응형

동일한 키를 가진 개체가 ObjectStateManager에 이미 있습니다. ObjectStateManager는 동일한 키로 여러 개체를 추적 할 수 없습니다.


기본적으로 회사에 대한 몇 가지 속성이 포함 된 테이블이 있습니다. 이것은 "마스터"테이블이며 해당 ID는 다른 많은 테이블에서 사용됩니다. 기본적으로이 방법을 통해 ID를 찾습니다.

private Company currentcompany()
    {
        Company cuco = db.Companies.Single(x => x.username == User.Identity.Name);
        return cuco;
    }

사용자에게이 테이블에 저장된 자신에 대한 다양한 세부 정보를 업데이트 할 수있는 기능을 제공해야하는데, 제가 완벽하게 잘 수행했지만 큰 보안 허점을 발견했습니다!

Firefox에서 Tamper Data를 사용하면 (그리고 Fidler / 많은 다른 사람들이 상상합니다) 숨겨진 ID를 쉽게 변경하고 다른 회사 세부 정보를 수정할 수 있습니다.

이를 중지하기 위해 수정 작업에 다음 줄을 추가했습니다.

        Company cuco = currentcompany();

        if (company.id != cuco.id)
        {
            return Content("Security Error");
        }

(참고- Company회사를 나타내는 모델 / POCO이며 company그 자체가 양식 데이터입니다.)

이것을 추가 한 후 폼 데이터에서 ID를 편집하면 예상대로 동작하고 "Security Error"가 나오지만, 오류가없고 계속하면 질문에 오류가 발생합니다.

"동일한 키를 가진 개체가 ObjectStateManager에 이미 있습니다. ObjectStateManager는 동일한 키를 가진 여러 개체를 추적 할 수 없습니다."

나는 이것이 EF가 어떻게 든 첫 번째 데이터 풀을 감지하고 유지하기 때문이라고 생각하지만 수정하는 방법을 잘 모르겠습니다.

어떤 충고?

편집--업데이트-

내가 달성하려는 것을 이해할 수 있다면이 문제를 해결하는 더 좋은 방법이 있습니까?


컨텍스트에서 엔터티를로드하는 경우 동일한 키로 엔터티를 다시 연결할 수 없습니다. 첫 번째 엔티티는 여전히 내부 컨텍스트 캐시에 보관되고 컨텍스트는 유형별로 지정된 키 값을 가진 하나의 인스턴스 만 보유 할 수 있습니다 (ID 맵이라고 하며 여기 에서 다른 상황에서 설명했습니다 ).

이전 인스턴스를 분리하여 해결할 수 있지만 반드시 그럴 필요는 없습니다. 새 값만 저장해야하는 경우 다음을 사용할 수 있습니다.

  • ObjectContext API : context.YourEntitySet.ApplyCurrentValues(newEntity);
  • DbContext API : context.Entry(oldEntity).CurrentValues.SetValues(newEntity);

oldEntityLadislav에 따라 as 를 찾는 방법을 모르는 경우 약간의 도움이 필요합니다 .

var entityKey = context.NewEntitySet.Create().GetType().GetProperty("Id").GetValue(newEntity);

factory.Entry(context.Set<NewEntityType>().Find(entityKey)).CurrentValues.SetValues(newEntity);

오류가 명확하게 언급했듯이 기존 항목 가져 와서 업데이트 된 정보로 해당 항목 데이터수정 하고 저장해야합니다. IDForeignKey ID 같은 주요 정보가 아닌 매우 구체적인 정보를 업데이트하면이 문제가 발생하지 않습니다.
아래 코드가 작업을 수행해야합니다!

 public virtual void Update(TEntity entity)
    {
        _context.Entry(entity).State = EntityState.Modified;

        this._context.SaveChanges();
    }

사용법은-

 public async Task<bool> UpdateVendorItem(string userId, Vendor modified)
    {

        try
        {
            var existing = await this.GetVendors().SingleOrDefaultAsync(a => a.Id == modified.Id);


            //Set updated info
            existing.VendorName = modified.VendorName;

            //Update address information
            existing.Address.AddressLine1 = modified.Address.AddressLine1;
            ... 

            await _vendorRepository.UpdateAsync(existing);

    ...

어제이 문제를 봤습니다. 업데이트하기 전에 cuco를 분리해야합니다. 답변 의 솔루션을 확인하십시오.

참고 URL : https://stackoverflow.com/questions/6033638/an-object-with-the-same-key-already-exists-in-the-objectstatemanager-the-object

반응형