场景是:
class Foo {
[Key]
public int Id { get; set; }
public List<Bar> Bars { get; set; }
}
class Bar {
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
我必须实现这样一个简单的讨论:
public void InsertOrUpdateFoo(Foo foo) {
var db = new MyContext();
//here some pseudocode
if (foo exists) {
d.Foos.Add(foo);
} else {
//here which is the best solution?
//a good tradeoff between performance and code semplicity
//case 1: delete first and add
db.Foos.Remove(oldFoo);
db.Add(foo);
db.SaveChanges();
//case 2: there is some functionality that allows you to update the entity like:
db.Modify(oldEntity, newEntity);
}
db.Dispose();
}
在更新场景中,这似乎是最佳选择?
答案 0 :(得分:0)
根据http://forums.asp.net/t/1889944.aspx中的想法,您可以检查实体的ID属性是否为默认值,例如0表示int。如果是这样,它是新的,应该添加。如果没有,那么更新它。
一旦实体附加到上下文,就可以通过其EntityState
向上下文指示。您可以通过上下文的DbEntityEntry
方法通过实体的Entry<T>()
获取对此内容的访问权。
您还需要在创建上下文时使用using
语句,该语句将管理上下文的范围,并在块结束时自动调用Dispose
。
最好将其拆分为实际保存更改的部分作为插入或更新(存储库方法,很可能,但为了简单起见将在此处单独使用)以及操作实体的代码。
方法的定义(基于您的代码):
public void InsertOrUpdateFoo(DbContext db, Foo foo) {
if (foo.ID == 0) { // assuming Foo's unique identifier is named ID
db.Entry(entity).State = EntityState.Added;
} else {
db.Entry(entity).State = EntityState.Modified;
}
db.SaveChanges();
}
用法:
// for when you're creating new entities
var newFoo = new Foo();
newFoo.Name = "A Name";
using(var context = new MyContext())
{
context.Add(newFoo);
InsertOrUpdate(context. newFoo);
}
// ...
// for when you're using existing entities
// you have an ID from somewhere in variable "id"
using (var context = new MyContext())
{
var existingFoo = context.Find(id);
if (existingFoo != null)
{
existingFoo.Name = "ChangedTheName";
InsertOrUpdate(context, existingFoo);
}
}