0

我正在尝试使用实体框架和 ICollection 子属性更新数据库数据。

对于 INSERT 情况,EF 会自动保存子数据,但对于 Updating 情况则不会。

所以我进行了手动更新,但我想有一种我不知道的自动更新方法。

请检查我的代码,并给我建议

public class Parent
{
    [Key]
    public int ID {get; set;}   
    public string Name {get; set;}

    public virtual ICollection<Child> Children{ get; set; }
}

public class Child
{
    [Key]
    public int ID {get; set;}
    public int ParentID { get; set; }
    public string Name {get; set;}
}

// INSERT 的控制器方法

public void InsertTest(){
    //generate new Parent Data with child
    Parent parent = new Parent() { 
        Name = "Nancy"
    };

    parent.Children.Add(new Child()
    {
        Name = "First Son"
    });

    parent.Children.Add(new Child()
    {
        Name = "Second Son"
    });

    var parentRepository = unitofwork.parentRepository;
    parentRepository.insert(parent); //context.Set<Parent>().Add(parent);
    unitofwork.Save();
    // it save child entity well
}

// UPDATE的控制器方法

public void UpateTest()
{
    //generate new Parent Data with child
    Parent parent = new Parent()
    {
        ID = 1,
        Name = "Nancy"
    };

    parent.Children.Add(new Child()
    {
        ID = 1,
        ParentID = 1,
        Name = "First Son Renamed"
    });

    parent.Children.Add(new Child()
    {
        ID = 2,
        ParentID = 1,
        Name = "Second Son"
    });

    // add new data
    parent.Children.Add(new Child()
    {
        Name = "Third Son"
    });

    var parentRepository = unitofwork.parentRepository;
    parentRepository.update(parent); //context.Set<Parent>().Attach(entityToUpdate); context.Entry(entityToUpdate).State = EntityState.Modified;
    unitofwork.Save();
    // it save parent data, but it does not change any for child data

    // *** To make work, I did like this, ***
    // var childRepository = unitofwork.childRepository;
    //foreach (Child c in parent.Children.ToList())
    //{
    //    if (c.ID < 1)
    //    {
    //        childRepository.update(c);
    //    }
    //    else
    //    {
    //        childRepository.insert(c);
    //    }
    //}

    //unitofwork.Save();

    // then it works.
}
4

1 回答 1

1

由于您没有直接附加所选内容并将它们标记为脏,因此 EF 无法在不丢失数据库原始值的情况下检测它们是否已更改。

从数据库中加载子项并将值注入其中(特别有用,如果您还想删除列表中不再选择的选项)或使用工作单元在附加它们后将已选择标记为已修改(但是,较少的 dB 操作,不会删除现有的孩子)。

从您的代码中,我假设 update() 方法是将实体标记为脏的方法。

于 2013-02-21T00:28:15.283 回答