2011-07-03 5 views
5

내 사용자로부터 합리적으로 자주 오류 보고서를지고있어 변경되지 행, 일반적인 일입니다 LINQ의 충돌이 - 발견 또는

Error Message: Row not found or changed. 
Stack Trace: 
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) 
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) 
at Controls_Article_ArticleViewer.LoadArticle() 
at ViewTutorial.Page_Load(Object sender, EventArgs e) 
at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) 
at System.Web.UI.Control.LoadRecursive() 
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 

가 (필요한 경우 좀 더 세부 사항을 제공 할 수 있습니다). 이 기능 LoadArticle()에서 유일하게 직접 LINQ 코드는 다음과 같습니다

using (MainContext db = new MainContext()) 
    { 
     var q = (
        from A in db.tblArticles 
        where A.ID == this.ArticleID && A.IsDeleted == false 
        select A 
       ).SingleOrDefault(); 
     if (q == null) 
     { 
      Server.Transfer("~/404.aspx"); 
      Context.Response.End(); 
     } 
     else 
     { 
      // Cache expired for HTML generation 
      if (q.HTMLLastGenerated.AddSeconds(Settings.ArticleRegenHTMLCacheSecs) < DateTime.Now) 
      { 
       q.Body = ArticlesCommon.Markdown(q.MarkupBody); 
       q.HTMLLastGenerated = DateTime.Now; 
      } 

      q.Views++; 
      q.LastView = DateTime.Now; 
      db.SubmitChanges(); 

      // Set passbakcs 
      this.AuthorID = q.AuthorID; 
      this.Anchor = q.Anchor; 
      this.SectionID = q.SectionID; 
      this.Views = q.Views; 
      this.DatePublished = q.Date; 
      ArticleAnchor = q.Anchor; 
      ArticleAuthorID = q.AuthorID; 

      // Get the latest edit 
      ArticleEdit LatestEdit = ArticleEditCommon.GetLatestEdit(this.ArticleID); 
      // An edit exists! 
      if (LatestEdit.ID != 0) 
      { 
       this.Description = LatestEdit.Description; 
       this.ArticleTitle = LatestEdit.Title; 
       ArticleBody.Text = LatestEdit.Body; 
       ArticleH1.Text = ArticleTitle; 
      } 
      // No edits 
      else 
      { 
       this.Description = q.Description; 
       this.ArticleTitle = q.Title; 
       ArticleBody.Text = q.Body; 
       ArticleH1.Text = ArticleTitle; 
      } 

      // Get toal comments 
      TotalComments = (from C in db.tblComments where C.IsDeleted == false && C.Anchor == ArticleAnchor select new { C.ID }).Count(); 

      // Get author details 
      var qq = (from A in db.tblForumAuthors where A.Author_ID == ArticleAuthorID select new { A.Username }).Single(); 
      AuthorUsername = qq.Username; 
     } 
    } 

이 LINQ를 실행하는 방법을 참조 LoadArticle 다른 기능을 할 수 있지만 위의 코드를 원인 그래서 나는, 스택 트레이스가 다르게 나올 것이라고 추측하고있다 .

이 문제의 원인은 무엇입니까? 데이터 충돌? 이 종류의 오류는 일반적으로 어떻게 해결됩니까?

어떤 아이디어가 발생합니까?

+0

동시 업데이트가이 문제를 트리거 할 수 있습니다. 거기에 어떤 위험이 있습니까? – bzlm

+0

@Bzlm, 예, 그렇습니다. 'LastViewed'필드가 고통을 겪을 수 있습니다.이 사이트를 처리하기 위해 어떤 것도 만들지 않았습니다. 이런 종류의 일이 발생할 가능성이 더 높기 때문에 Google 사이트의 색인 생성 속도가 증가 했습니까? –

+0

그리고'ArticlesCommon.Markup (q.MarkupBody)'도 상당히 느린 것일 것입니다. 아마도 누군가 그 것을 보려고 할 때 실행되고, 이것을 해결하는 방법이 있을까요? –

답변

6

L2S의 업데이트 확인 메커니즘이 부담이되고 도움이되지 않습니다. 동시성 보호가 필요하다면 아마 그 코드를 남겨 두어야 할 것입니다.하지만 제 경우에는 수표를 사용하지 말고 그의 마지막 편집을 맡기는 것이 충분합니다. 이를 위해 더 많은 차별을할만한 이유가 있지만 모든 열에 대한 모든 업데이트 확인을 비활성화했습니다. 당신의 속성을 정의 할 때 이렇게하려면 ColumnAttributeUpdateCheck 속성을 사용 :

, 내가 어떤 시설이 믿지 않는 말했다되고 그건
[Column(Storage="lastView", Name="LastView", 
DbType="datetime", UpdateCheck=UpdateCheck.Never)] 
public DateTime LastView { ... } 

sqlmetal/DBML 당신이 가진 것, 그래서 당신을 위해이 작업을 수행하는 엔티티 클래스를 직접 생성해야합니다 (어쨌든 나쁜 아이디어는 아닙니다. 매우 강력합니다).

+2

나는 Linq To SQL이 업데이트시 열을 검사하고 때로 SQL Server의 열이 .dbml 파일에서 변경 될 수 있다고 생각합니다. 다음은 도움이되는 대체 답변입니다. http://stackoverflow.com/questions/4104797/row-not-found-or-changed-linq-c-sharp-error-on-simple-statement-help-please – JoshVarty

0

dbml 파일에 테이블을 추가 한 경우 업데이트 및 삭제 만 수행 할 수 있습니다. 엔티티를 수작업으로 처리 한 경우 업데이트 및 삭제를 수동으로 처리해야합니다.

2

내 오류로 인해 데이터베이스에 트리거가있어서 업데이트하려고 시도했던 행이 변경되었습니다. 내 DbContext에는 트리거가 변경되지 않았습니다. 내가 찾은 해결책은 DbContext.Refresh() 메서드를 호출하는 것이 었 : 같은 행에

var productToUpdate = _dbContext.Products.SingleOrDefault(p => p.ID == product.ProductID); 
_dbContext.Refresh(RefreshMode.OverwriteCurrentValues, productToUpdate); 

// do changes... 
_dbContext.SubmitChanges();