更新Entity Framework中包含其他实体列表的实体

时间:2015-01-23 17:13:52

标签: c# entity-framework asp.net-web-api

我正在尝试更新实体框架中的对象,我想知道更新包含其他实体列表的实体的最佳方法。

考虑以下示例:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EntityFrameworkUpdateSketch
{
public class A
{
    [Key]
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)]
    public int Akey {get;set;}

    public string Aname { get; set; }

    public virtual List<B> Blist {get;set;}

    public A()
    {
        Blist = new List<B>();
    }
}

public class B
{
    public virtual A owner { get; set; }

    [ForeignKey("owner")]
    [Key, Column(Order = 0)]
    public int Akey { get; set; }

    [Key, Column(Order = 1)]
    public int Order { get; set; }


    public string Bname { get; set; }
}

public class Database: DbContext
{
    public DbSet<A> As { get; set; }
    public DbSet<B> Bs { get; set; }
}

public class Program
{        
    static void Main(string[] args)
    {
        // Make a new object

        using (Database db = new Database())
        {
            A intodb = new A();

            intodb.Akey = 1;                

            intodb.Aname = "Name of A object";

            intodb.Blist.Add(new B() { Bname = "Name of B object one",Order=1 });

            intodb.Blist.Add(new B() { Bname = "Name of B object two",Order=2 });

            db.As.Add(intodb);

            db.SaveChanges();
        }

        // Update the object in database

        using (Database db = new Database())
        {                       
            // Imagine I got "update" from somewhere else

            A update = new A();

            update.Akey = 1;

            update.Aname = "New Name of A object";

            update.Blist.Add(new B() { Bname = "New Name of B object one" ,Akey=1, Order=1});

            update.Blist.Add(new B() { Bname = "New Name of B object two", Akey = 1, Order = 2 });

            update.Blist.Add(new B() { Bname = "A whole new object 3", Akey = 1, Order = 3 });


            db.Entry<A>(update).State = EntityState.Modified;                

            db.SaveChanges();
        }
    }
}
}

我有一个包含List作为属性的对象“A”。

在演示程序的前半部分,我创建了一个A类型的新对象,然后将其存储在数据库中。

在下半部分,我创建了一个名为A的新对象,我想用新值更新数据库中的对象 - 我想更改B名称,并且我想在列表中添加一个新的B对象。 / p>

这适用于更改A,但子类别B不起作用 - 它们没有新名称。

我尝试这样做的原因是因为我正在尝试为MVC WebAPI控制器编写PUT方法,该控制器将其数据存储在Entity Framework中。我正在将一个新对象传入我的PUT操作,我想替换数据库中的现有对象。

我无法删除A并重新添加它(尽管这确实有效)因为这会破坏外键 - 我在“真实”解决方案中有级联删除,如果我删除了我的A对象,则删除其他地方的引用。

您无需了解任何有关WebAPI或PUT的内容即可回答此问题。

1 个答案:

答案 0 :(得分:0)

这是一个有效但可以改进的程序。所有这个程序现在都是删除数据库中属于A的所有B对象,然后重新添加。这有效,但似乎很糟糕。有什么改进吗?

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EntityFrameworkUpdateSketch
{
public class A
{
    [Key]
    [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)]
    public int Akey {get;set;}

    public string Aname { get; set; }

    public virtual List<B> Blist {get;set;}

    public A()
    {
        Blist = new List<B>();
    }
}

public class B
{
    public virtual A owner { get; set; }

    [ForeignKey("owner")]
    [Key, Column(Order = 0)]
    public int Akey { get; set; }

    [Key, Column(Order = 1)]
    public int Order { get; set; }


    public string Bname { get; set; }
}

public class Database: DbContext
{
    public DbSet<A> As { get; set; }
    public DbSet<B> Bs { get; set; }
}

public class Program
{        
    static void Main(string[] args)
    {
        // Make a new object            
        using (Database db = new Database())
        {
            A intodb = new A();

            intodb.Akey = 1;                

            intodb.Aname = "Name of A object";

            intodb.Blist.Add(new B() { Bname = "Name of B object one",Order=1 });

            intodb.Blist.Add(new B() { Bname = "Name of B object two",Order=2 });

            db.As.Add(intodb);

            db.SaveChanges();
        }

        // Update the object in database

        using (Database db = new Database())
        {                       
            // Imagine I got "update" from somewhere else

            A update = new A();

            update.Akey = 1;

            update.Aname = "New Name of A object";

            update.Blist.Add(new B() { Bname = "New Name of B object one" ,Akey=1, Order=1});

            update.Blist.Add(new B() { Bname = "New Name of B object two", Akey = 1, Order = 2 });

            update.Blist.Add(new B() { Bname = "A whole new object 3", Akey = 1, Order = 3 });


            db.Entry<A>(update).State = EntityState.Modified;                

            // Clear all existing B objects attached to the updated object

            var query = from c in db.Bs.AsEnumerable() where  c.Akey==update.Akey select c;

            foreach (var z in query)
            {
                db.Bs.Remove(z);
            }

            // Readd B objects

            foreach (var i in update.Blist)
            {
                db.Bs.Add(i);
            }

            db.SaveChanges();                              
        }
    }

}
}