实体框架关系未更新

时间:2014-05-23 08:46:27

标签: c# entity-framework

我遇到的问题是更新实体不会更新与之相关的实体。以下是代码示例。

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.

如何更新Bars,而无需从数据库中选择它们?

由于

更新

我已经修改了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)的第一个版本也能正常工作(添加所有条形码)。然而,这是更新,但没有。

1 个答案:

答案 0 :(得分:0)

您可能会注意到,如果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.
    }
}

尝试以上方法。当我遇到类似问题时发生的事情是&#34; new&#34;保存的栏和现有的栏无效。

您可以尝试的下一步是在更新时进行一些手动删除:

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();
}

让我知道它是否适合你。