동일한 키를 가진 개체가 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);
oldEntity
Ladislav에 따라 as 를 찾는 방법을 모르는 경우 약간의 도움이 필요합니다 .
var entityKey = context.NewEntitySet.Create().GetType().GetProperty("Id").GetValue(newEntity);
factory.Entry(context.Set<NewEntityType>().Find(entityKey)).CurrentValues.SetValues(newEntity);
오류가 명확하게 언급했듯이 기존 항목 을 가져 와서 업데이트 된 정보로 해당 항목 데이터 를 수정 하고 저장해야합니다. ID 및 ForeignKey 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를 분리해야합니다. 이 답변 의 솔루션을 확인하십시오.
'IT Share you' 카테고리의 다른 글
Linux SUSE 또는 RedHat에서 Python 2.7을로드하는 방법 (0) | 2020.12.06 |
---|---|
PDF에 빈 줄을 삽입하는 방법은 무엇입니까? (0) | 2020.12.06 |
대화 상자가 1 초 동안 실행되고 사라집니다. (0) | 2020.12.06 |
symfony2 : 캐시 디렉토리를 쓰지 못했습니다. (0) | 2020.12.06 |
IE10이 텍스트 상자에 삽입하는 지우기 버튼을 비활성화하려면 어떻게해야합니까? (0) | 2020.12.06 |