实体框架关系没有更新

本文关键字:更新 关系 框架 实体 | 更新日期: 2023-09-27 18:04:56

我遇到了一个问题,通过更新实体不更新与之相关的实体。下面是一个示例代码:

public class Foo
{
    public int Id { get; set; }
    public virtual ICollection<Bar> Bars { get; set; }
    public virtual string SomeString { get; set; }
}
public class Bar
{
    public int Id { get; set; }
}
public class FooMapping : EntityTypeConfiguration<Foo>
{
    public FooMapping()
    {
        HasKey(f => f.Id);
        HasMany(f => f.Bars);
    }
 }

public class MyDb : DbContext
{
    public IDbSet<Foo> Foos { get; set; }
    public IDbSet<Bar> Bars { get; set; }
    protected override vod OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Configurations.Add(new FooMapping());
    }
}

我从外部应用程序收到一个包含fooobject的更新命令,如下所示:

public void Update(Foo foo)
{
    _myDb.Entry(foo).State = EntityState.Modified;
    _myDb.SaveChanges();
}

这正确地更新了SomeString的值,但是Bar对象没有被修改。

我已经试过了:

public void Update(Foo foo)
{
    foreach(Bar bar in foo.Bars)
    {
        _myDb.Entry(bar).State = EntityState.Modified;
    }
    _myDb.Entry(foo).State = EntityState.Modified;
    _myDb.SaveChanges();
}

,但这给出了一个DbUpdateConcurrencyException,带有以下信息

Store update, insert, or delete statement affected an unexpected
number of rows (0). 
Entities may have been modified or deleted since entities were loaded. Refresh 
ObjectStateManager entries.

我怎样才能得到酒吧更新,而不必从数据库中选择他们?

感谢

我已经这样修改了Bar实体和映射。

public class Bar
{
    public int Id { get; set; }
    public virtual Foo Foo { get; set; }
}
public class FooMapping : EntityTypeConfiguration<Foo>
{
    public FooMapping()
    {
        HasKey(f => f.Id);
        HasMany(f => f.Bars).WithRequired(b => b.Foo);
    }
 }
public class BarMapping : EntityTypeConfiguration<Foo>
{
    public BarMapping()
    {
        HasKey(b => b.Id);
        HasRequired(b => b.Foo);
    }
 }

这不会改变任何东西。我应该提到的是,即使使用_myDb.Foos.Add(foo)的第一个版本也可以正常工作(添加所有bar)。然而,它是更新没有。

实体框架关系没有更新

您可能会注意到,如果Foo有新的Bar项,它们将被添加,并且(可能)现有的将被取消。您可以尝试以下方法:

将Bar关联到Foo:

public class Bar
{
    public int Id { get; set; }
    public virtual Foo Foo { get; set; }
}
public class FooMapping : EntityTypeConfiguration<Foo>
{
    public FooMapping()
    {
        HasKey(f => f.Id);
        HasMany(f => f.Bars)
            .WithRequired(b => b.Foo); //check this syntax, I'm not entirely sure.
    }
}

试试上面的方法。当我遇到类似的问题时,发生的事情是"新"栏被保存,而现有的栏被取消。

下一步你可以尝试在更新时做一些手动删除:

public void Update(Foo foo)
{
    var existing = _myDb.Find(foo.Id);
    foreach(Bar bar in existing.Bars.ToList()) 
    {
        _myDb.Remove(bar);
    }
    existing.Bars.Clear();
    foreach(Bar bar in foo.Bars)
    {
        existing.Bars.Add(bar);
    }
    // map other properties...
    _myDb.SaveChanges();
}

让我知道它是否适合你