为什么我会收到“未找到或更改行”信息此处出错?

发布于 2024-12-17 07:23:52 字数 1070 浏览 3 评论 0原文

我已经在谷歌上搜索了“未找到或更改行”错误一段时间,但我只是无法看到该错误是如何在我的应用程序中引起的。

我有一个名为 DataAccess 的外观类,它包装多个存储库,并在我的应用程序中传递。每个控制器都依赖于 DataAccess,因此我将其连接到 unity 以根据需要进行传递。

数据访问以截断/抽象的形式大致如下所示:

public class DataAccess : IDataAccess
{
    private MyDataContext DataContext = new MyDataContext();

    public Repository1 Repo1 = new Repository1();
    public Repository2 Repo2 = new Repository2();

    public DataAccess()
    {
        Repo1.DataContext = DataContext;
        Repo2.DataContext = DataContext;
    }
}

然后每个控制器都依赖于 IDataAccess,如下所示:

public class MyControllerBase
{
    [Dependency]
    IDataAccess DataAccess { get; set; }
}

Unity 根据看似正常的配置分发这些内容,在 Global.asax 中注册类型,将控制器连接到工厂,统一解决。此外,我已经使用 PerThreadLifetimeManager() 注册了它,我不确定这是否正确。

在大多数情况下,这效果很好 - 但是可以通过以下方式重现问题:

  • 转到编辑操作并发布编辑(重定向到索引)
  • 返回到编辑操作并尝试发布另一个编辑,或者进入删除操作并尝试在同一项目上发布删除

这会引发“未找到或更改行”错误。每个操作(编辑和删除)都会调用 DataContext 上的 SubmitChanges()。所以我不太确定这里发生了什么。如果有人有任何想法,他们会非常受欢迎。

干杯,

蒂姆。

I've googled around the "Row Not Found or Changed" error for some time, and I'm just unable to see how the error is being caused in my application.

I have a facade class, called DataAccess, which wraps multiple repositories, and gets passed around my application. Every controller has a dependency upon DataAccess, so I've hooked it up to unity to pass out as required.

Data Access looks roughly like this, in truncated/abstracted form:

public class DataAccess : IDataAccess
{
    private MyDataContext DataContext = new MyDataContext();

    public Repository1 Repo1 = new Repository1();
    public Repository2 Repo2 = new Repository2();

    public DataAccess()
    {
        Repo1.DataContext = DataContext;
        Repo2.DataContext = DataContext;
    }
}

Then each controller has a dependency upon IDataAccess like so:

public class MyControllerBase
{
    [Dependency]
    IDataAccess DataAccess { get; set; }
}

Unity hands these out according to what appears to be normal configuration, registering types in Global.asax, hooking controllers up to a factory, resolving with unity. Furthermore, I've registered it with a PerThreadLifetimeManager(), which I am unsure whether is correct.

For the most part this works great - however the problem can be reproduced by:

  • Go to Edit action and post an edit (redirects to Index)
  • Go back into the Edit action and attempt to post another edit, OR, go into Delete action and attempt to post a Delete on the same item

This throws the "Row Not Found or Changed" error. Each action (Edit and Delete) calls SubmitChanges() on the DataContext. So I'm not quite sure what's going on here. If anyone has any ideas they would be extremely well received.

Cheers,

Tim.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

云之铃。 2024-12-24 07:23:52

我怀疑每个线程的生命周期在这里不合适 - ASP.NET 跨请求重用线程,这将导致跨多个请求重用旧上下文,可能使它们处于奇怪的状态。

你有两个选择:

  1. 如果你只在控制器上调用container.resolve,那么你可以使用内置的PerResolveLifetimeManager。这将为每个控制器解析提供一个 DataAccess 对象。
  2. 您可以获取众多 PerRequestLifetimeManager 实现之一,并为每个 HttpRequest 获取一个新的 DataAccess 对象。

我怀疑,无论哪种方式都会让你摆脱目前遇到的问题。

I suspect the per-thread lifetime is not appropriate here - ASP.NET reuses threads across requests, and that would result in reusing your old contexts across multiple requests, possibly leaving them in odd states.

You have two choices:

  1. If you only call container.resolve on the controller, then you could use the built-in PerResolveLifetimeManager instead. This would give you a single DataAccess object per controller resolve.
  2. You could grab one of the many PerRequestLifetimeManager implementations and get a new DataAccess object per HttpRequest.

Either way will, I suspect, get you out of the issues you've got currently.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文