我从用户那里得到了相当频繁的错误报告,典型的一个是:
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;
}
}
LoadArticle
中可能有其他函数引用运行LINQ的方法,但我猜测堆栈跟踪的结果会有所不同,所以上面的代码就是原因。
关于导致这种情况的任何想法?数据冲突?这种错误通常是如何解决的?
任何想法会导致什么?
答案 0 :(得分:6)
我发现L2S中的更新检查机制是一种负担并且无益。如果你需要并发保护,那么你应该把它们留进去。但在我的情况下,免除支票并让最后一个保留他的编辑对我来说已经绰绰有余了。为此,我禁用了所有列的所有更新检查,尽管您可能有理由更具辨别力。为此,请在定义属性时使用UpdateCheck
ColumnAttribute
属性:
[Column(Storage="lastView", Name="LastView",
DbType="datetime", UpdateCheck=UpdateCheck.Never)]
public DateTime LastView { ... }
话虽这么说,我不相信sqlmetal / dbml中有任何设施可以为你做这个,所以你必须自己生成实体类(不管怎样都不是一个坏主意 - 非常强大)。 / p>
答案 1 :(得分:2)
我遇到了同样的错误,在我的情况下,数据库上的触发器改变了我试图更新的行。我的DbContext
没有触发所做的更改。
我找到的解决方案是在.Refresh()
上调用DbContext
方法:
var productToUpdate = _dbContext.Products.SingleOrDefault(p => p.ID == product.ProductID);
_dbContext.Refresh(RefreshMode.OverwriteCurrentValues, productToUpdate);
// do changes...
_dbContext.SubmitChanges();
答案 2 :(得分:0)
如果已将表添加到dbml文件,则仅更新和删除即可使用。如果您手动编码了实体,则必须手动处理更新和删除