无法在数据库更新中保存更改。奇怪的懒惰加载行为可能吗? [英] Unable to SaveChanges on a db update. Weird lazy loading behavior possibly?

查看:120
本文介绍了无法在数据库更新中保存更改。奇怪的懒惰加载行为可能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,我的代码看起来像这样简单:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆