2011-05-16 2 views
3

this question을 확인했으며 필요한 내용과 관련이있는 것 같지만 정확하게 대답하지 않습니다.ASP.NET MVC3 코드 - 첫 번째 오류 - 엔티티를 업데이트하려고 시도합니다.

MVC3 작동 방식에 대한 내 자신의 교육 이해를위한 "문제점"(일반적인 문제 추적)에 대한 엔티티 (MVC3-를 통해 EF 코드를 사용하여 SQL Compact를 통해 첫 번째로 압축 한 경우)가 있습니다. Issue 클래스에는 CreatedBy 속성 (이슈를 만든 사용자에 대한 Int 참조)과 CreatedDate 속성 (DateTime)이 있습니다. 내가 업데이트 할 스캐 폴딩 코드를 사용하는 경우 (사용자에 의해 수정되는 일부 업데이트 된 날짜 필드를 방지하기 만 수정) :

 if (ModelState.IsValid) 
     { 
      issue.LastActivity = (DateTime?)DateTime.Now.Date; 
      if (issue.ClosedBy != null) issue.ClosedDate = (DateTime?)DateTime.Now.Date; 
      startingIssue = null; 
      db.Entry(issue).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 

가 나는에 DATETIME2 데이터 형식의 (변환 링크 된 질문에서 언급 한 오류가 나타납니다 날짜/시간 데이터 형식 등)

코드를 단계별 실행하면 내 CreatedBy 및 CreatedDate 속성이 컨트롤러가 지나가고있는 issue의 인스턴스에 포함되지 않은 것처럼 보입니다. 제가 DB에서 문제의 또 다른 사본을 잡아와 값들을 업데이트하여이 문제를 해결하려고 할 때 :

 var startingIssue = db.Issues.Find(issue.IssueId); 
     if (ModelState.IsValid) 
     { 
      if (issue.CreatedBy != startingIssue.CreatedBy) issue.CreatedBy = startingIssue.CreatedBy; 
      if (issue.CreatedDate != startingIssue.CreatedDate) issue.CreatedDate = startingIssue.CreatedDate; 
      issue.LastActivity = (DateTime?)DateTime.Now.Date; 
      if (issue.ClosedBy != null) issue.ClosedDate = (DateTime?)DateTime.Now.Date; 
      startingIssue = null; 
      db.Entry(issue).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 

을 나는 동시성 위반을 얻을 : 같은 키를 가진 개체가 이미 ObjectStateManager에 존재합니다. ObjectStateManager는 동일한 키가있는 여러 객체를 추적 할 수 없습니다.

그래서 DB에 이미 설정된 날짜를 볼 수 있도록 EF를 가져 오므로 (동시 작성을 위반하지 않고 CreatedDate를 1/1/0001로 업데이트하려고하지는 않습니다)?

편집 좋아 ... 찾았습니다. 나는 분명히 @Html.HiddenFor(model => model.[property])을 찾고 어쨌든 뷰에 에디터를 추가했다. 그것은 나에게 다소 어리석은 듯하지만, 하나의 객체를 분리하고 업데이트 된 객체를 대체하기 위해 사용자 정의 코드를 추가하지 않고도 작동합니다.

답변

15

간단히 대답하면 Find이라는 컨텍스트에 이미 엔티티를로드 했으므로 나중에 다른 엔티티를 첨부 할 수 없다는 것입니다.

두 가지 옵션이 남아 있습니다 :

  • 분리 첫 번째 인스턴스, 나는이 코드를 공유 할 첫 번째

에 두 번째

  • 복사를 두 번째 인스턴스에서 필드를 부착 첫 번째 옵션입니다. 먼저, DbContext 구현에 Detach 방법을 추가

    public void Detach(object entity) 
    { 
        var objectContext = ((IObjectContextAdapter)this).ObjectContext; 
        objectContext.Detach(entity); 
    } 
    

    을 다음 Detach를 호출하는 대신 변수를 설정하는 null

    var startingIssue = db.Issues.Find(issue.IssueId); 
    if (ModelState.IsValid) 
    { 
        if (issue.CreatedBy != startingIssue.CreatedBy) issue.CreatedBy = startingIssue.CreatedBy; 
        if (issue.CreatedDate != startingIssue.CreatedDate) issue.CreatedDate = startingIssue.CreatedDate; 
        issue.LastActivity = (DateTime?)DateTime.Now.Date; 
        if (issue.ClosedBy != null) issue.ClosedDate = (DateTime?)DateTime.Now.Date; 
    
        // startingIssue = null; 
        db.Detach(startingIssue); 
    
        db.Entry(issue).State = EntityState.Modified; 
        db.SaveChanges(); 
        return RedirectToAction("Index"); 
    } 
    
  • +0

    그건 그렇습니다. 감사.다른 사람들이보다 우아한 해결책을 제공하는지 기다릴 수는 있지만, 그렇지 않다면 나는 받아 들인 대답으로 당신을 선택할 것입니다. – AllenG

    +0

    내 업데이트보기 - 포인트를 제공합니다. – AllenG

    +1

    나는 비슷한 문제가 있었다. 새 레코드를 만들 때 설정해야하는 내 테이블 (CreatedBy, CreatedOn)에 감사 필드가 있는데 내 MVC 사이트의 페이지를 편집하기 위해 전달하지 않습니다. 그래서 새 레코드를 편집 할 때 DB에서 현재 감사 값을 읽고 DBContext에 저장하기 전에 들어오는 개체를 업데이트해야합니다. 이렇게하려면 (ID)를 찾아 현재 값을 가져온 다음 분리를 수행해야합니다. 내 질문/답변은 http://stackoverflow.com/questions/8145635/what-is-the-best-way-to-maintain-anentity-original-properties-when-theyare-n/8154045#입니다. 8154045 – kingdango

    0

    에 CreateDate 및 CreatedBy 필드는 편집 형태가 아닌 경우, 업데이트를 액션 객체는 db 값을 갖지 않습니다.

    편집 서식에 필드를 포함 시키면 Ed의 대답에 설명 된대로 db에 대한 추가 호출 및 재설정이 수행되지 않을 수 있습니다. 그런 다음 일반 모델 바인딩이 업데이트를 가져와 업데이트시 제공해야합니다.

    +1

    실제로 가능하지만 편집 가능합니다. 이미 텍스트처럼 값을 표시합니다. 값에 대한 편집자 필드를 추가하면 다른 방법으로 사용자가 실제로 문제가 10 일 전에 작성된 것이 아니라 이전에 실제로 작성된 것으로 결정하지 못하도록 노력해야합니다. – AllenG

    +1

    예, 숨겨진 필드를 사용하면 바인딩 작업이 가능하지만 필드를 일정하게 유지해야하는 경우 좋지 않은 조작을 해당 필드에 표시합니다. – kingdango

    관련 문제