I've been getting reasonably frequent error reports from my users, a typical one is:
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)
(I can give more specifics if needed). The only direct LINQ code in that function LoadArticle()
is:
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;
}
}
There may be other functions in LoadArticle
that reference methods that run LINQ, but I am guessing the stacktrace would come out differently, so the code above is the cause.
Any ideas as to what would cause this? A data conflict? How is this sort of error resolved usually?
Any ideas what would cause this?
I've found the update check mechanisms in L2S to be a burden and unhelpful. If you need the concurrency protection, then you should probably leave them in. But in my case, dispensing with checks and letting the last-one-in keep his edits was more than sufficient for me. To that end, I disabled all the update checks for all my columns, though you may have a reason to be more discriminating. To do so, use the UpdateCheck
property of ColumnAttribute
when defining your properties:
[Column(Storage="lastView", Name="LastView",
DbType="datetime", UpdateCheck=UpdateCheck.Never)]
public DateTime LastView { ... }
That being said, I don't believe there is any facility in sqlmetal/dbml to do this for you, so you'd have to generate the entity classes yourself (not a bad idea anyway -- very powerful).
I had the same error, in my case a trigger on the database changed the row I was trying to update. My DbContext
didn't had the change the trigger made.
The solution I found was to call the .Refresh()
method on the DbContext
:
var productToUpdate = _dbContext.Products.SingleOrDefault(p => p.ID == product.ProductID);
_dbContext.Refresh(RefreshMode.OverwriteCurrentValues, productToUpdate);
// do changes...
_dbContext.SubmitChanges();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With