2011-07-03 22 views
5

benim kullanıcılardan makul sık hata raporlar alıyoruz değişmedi Row, tipik bir tanesidir: LINQ çatışma - bulunamadı veya

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) 

(gerekirse daha fazla özelliklerini verebilir). Bu işlevin LoadArticle() yılında sadece doğrudan LINQ kodudur:

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; 
     } 
    } 

var LINQ çalıştırmak yöntemleri başvuru LoadArticle diğer fonksiyonlar olabilir, ancak Yukarıdaki kod nedenidir yüzden StackTrace farklı çıkacağını tahmin ediyorum .

Buna neyin sebep olacağı konusunda bir fikir var mı? Bir veri çakışması mı? Bu tür bir hata genellikle nasıl çözülür?

Herhangi bir fikir buna neye sebep olur?

+0

Eşzamanlı güncellemeler bu tetikleyebilir. Bunun riski var mı? – bzlm

+0

@Bzlm, Öyle sanıyorum ki, 'LastViewed' alanı bundan muzdarip olabilirdi, bu siteyi ele almak için hiçbir şey yapmadım. Sitemin Googles endeksleme oranını artırdım, bu yüzden bu tür bir şey daha olasıdır? –

+0

ve ayrıca 'ArticlesCommon.Markdown (q.MarkupBody)' oldukça yavaş bir tane olacak, bu muhtemelen bir suçlu, birileri onu görüntülemeye çalışırken ortaya çıkıyor ve fikirler bunu nasıl çözecek? –

cevap

6

L2S'deki güncelleme kontrol mekanizmalarını yük ve yardımcı olmak için buldum. Eşzamanlılık korumasına ihtiyacınız varsa, muhtemelen onları terk etmelisiniz. Ama benim durumumda, kontrolleri dağıtmak ve sonuncusunu bırakmak, onun düzenlemelerini benim için yeterli değildi. Bu amaçla, tüm sütunlarım için tüm güncelleme kontrollerini devre dışı bıraktım, ancak daha ayrıcalıklı olmanız için bir nedeniniz olabilir. senin özelliklerini tanımlarken Bunun için ColumnAttribute ait UpdateCheck özelliğini kullanın:

, ben herhangi bir tesis bulunmuyor inanmıyorum söyleniyor
[Column(Storage="lastView", Name="LastView", 
DbType="datetime", UpdateCheck=UpdateCheck.Never)] 
public DateTime LastView { ... } 

sqlmetal/dbml ederdiniz, böylece sizin için bunu yapmak varlık sınıflarını kendiniz üretmek için (zaten kötü bir fikir değil - çok güçlü).

+2

Sorun şu ki, Linq To Sql, sütunlarınızı güncelleştirme sırasında denetler ve bazen SQL Server'daki sütunlar .dbml dosyanızda değiştirilebilir. İşte yardımcı bulduğum alternatif bir cevap: http://stackoverflow.com/questions/4104797/row-not-found-or-changed-linq-c-sharp-error-on-simple-statement-help-please – JoshVarty

0

Tabloları dbml dosyasına eklediyseniz, güncelleştirme ve silme yalnızca kutudan çıkar. Eğer varlıkları handcoded varsa güncelleştirmeyi el ele ve ben veritabanı üzerinde bir tetikleyici Güncelleme için çalışıyordu satır değişti benim durumumda, aynı hata vardı

2

silmek zorunda kalacaktır. DbContext, tetiklemenin yapılmadığı değişikliğe sahip değildi. buldum çözümü DbContext üzerinde .Refresh() yöntemi çağırmak oldu: Aynı satıra

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

// do changes... 
_dbContext.SubmitChanges(); 
İlgili konular