我正在尝试更新实体框架中的对象,我想知道更新包含其他实体列表的实体的最佳方法。
考虑以下示例:
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的内容即可回答此问题。
答案 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();
}
}
}
}