无法在数据库更新中保存更改。奇怪的懒惰加载行为可能吗? [英] Unable to SaveChanges on a db update. Weird lazy loading behavior possibly?
问题描述
现在,我的代码看起来像这样简单:
Right now, my code looks as simple as this:
public class FooController : Controller
{
private readonly ApplicationDbContext db;
public FooController()
{
db = new ApplicationDbContext();
}
public ActionResult Update(int id)
{
Foo foo = db.Foos.Find(id);
foo.X = "new string";
db.SaveChanges();
return Redirect("Index", "Home");
}
}
假设Foo有一个属性X,一个字符串和酒吧酒吧,酒吧实体的集合。该属性的约束在集合中必须介于1到100条之间。
Assume Foo has a property X, a string, and a property Bars, a collection of Bar entities. There is a constraint on the property that there must be between 1 to 100 Bars in the collection.
我目前正在收到以下异常:
I am currently getting the following exception:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
我调试并打印出实际的错误:
which I debugged and printed out the actual error:
Property: "Bars", Error: "Must have between 1 and 100 bars"
这让我感到困惑,因为我知道这个特定的 foo
的实例在其集合中有5个Bars。所以我在 db.SaveChanges()
行上放置一个断点,并使用VS工具将鼠标悬停在foo实例上,发现它确实在集合中有5个Bars。当我继续运行程序时,更新成功完成。起初我以为这很奇怪。也许有一个低级别的竞争条件(我说低级别,因为我没有在应用程序级别做任何异步/线程),并且断点允许其他线程赶上。也就是说,直到我再次使用断点再次运行更新,而不用将悬停在foo实例上,等待几秒钟,并继续运行程序。返回的错误。
This confused me since I knew that that particular instance of foo
had 5 Bars in its collection. So I put a breakpoint on the db.SaveChanges()
line and used the VS tool to hover over the foo instance and discovered it did indeed have the 5 Bars in the collection. When I continued running the program, the Update successfully completed. At first I thought, that's weird. Maybe there's a low level race condition (I say low level because I'm not doing any async/threading at the app level) and the breakpoint allowed the other thread to catch up. That is, until I ran the update again with the breakpoint without hovering over the foo instance, waiting a few seconds, and continued the running of the program. The error returned.
所以我想当我将鼠标悬停在 foo
时,我正在加载东西,那个加载是保存更改是必需的。这是一个已知的问题?是否有其他部分的代码,我应该发布,以弄清楚发生了什么?
So I think I'm loading something lazily when I hover over foo
and that load is necessary for saving changes. Is this a known issue? Is there some other part of the code that I should post to figure out what's going on?
编辑:为了临时解决方法,如果这增加了更多的证据。以下补充允许该方法按照预期工作:
For a temporary workaround, and in case this adds more evidence. The following addition allows the method to work as intended:
public ActionResult Update(int id)
{
Foo foo = db.Foos.Find(id);
foo.X = "new string";
Debug.WriteLine(foo.Bars);
db.SaveChanges();
}
显然这是一个bandaid,我想知道真正的事情在这里。
Clearly this is a bandaid, and I'd like to know what's really going on here.
另一个编辑:添加如何在Foo.Bars上实现验证
Another Adding how validation is implemented on Foo.Bars
public class Foo
{
public string X {get;set;}
[MinMaxLength]
public virtual ICollection<Bar> Bars {get; set;}
}
MinMaxLength如下所示:
And MinMaxLength looks as follows:
public class MinMaxLength : ValidationAttribute
{
public int Min { get; set; } = 1;
public int Max { get; set; } = 100;
public MinMaxLength()
: base("Must have between 1 and 100")
{
}
public MinMaxLength(string errorMessage)
: base(errorMessage)
{
}
public override bool IsValid(object value)
{
if (value == null)
{
return true;
}
var coll = value as ICollection;
if (coll == null)
{
return false;
}
var count = coll.Count;
return count >= Min && count <= Max;
}
}
推荐答案
尝试这样的事情
public ActionResult Update(int id)
{
Foo foo = db.Foos.Find(id);
foo.X = "new string";
var entry = db.Entry(foo);
entry.State = EntityState.Modified;
db.SaveChanges();
// Rest of code
}
这篇关于无法在数据库更新中保存更改。奇怪的懒惰加载行为可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!