什么是最有效的方法来实现更新行,如果它存在,否则插入新的行逻辑使用实体框架?或者这有什么规律吗?
当前回答
Ladislav的答案很接近,但我不得不做了一些修改,以使其在EF6(数据库优先)中工作。我用我的AddOrUpdate方法扩展了我的数据上下文,到目前为止,这似乎与分离的对象工作得很好:
using System.Data.Entity;
[....]
public partial class MyDBEntities {
public void AddOrUpdate(MyDBEntities ctx, DbSet set, Object obj, long ID) {
if (ID != 0) {
set.Attach(obj);
ctx.Entry(obj).State = EntityState.Modified;
}
else {
set.Add(obj);
}
}
[....]
其他回答
试试这个算法
public void InsertOrUpdate(Item item)
{
using (var context = new ItemContext())
{
var existedItem = context.Items.Where(x => x.Id==item.Id).FirstOrDefault();
if(existedItem != null)
{
context.Entry(existedItem).CurrentValues.SetValues(item);
//or only if you want to update some special properties
existedItem.Prop1=item.Prop1;
existedItem.Prop2=item.Prop2
context.Entry(existedItem).State =EntityState.Modified;
//-----------
}
else
{
context.Items.Add(item);
}
context.SaveChanges();
}
}
如果你正在使用附加对象(从上下文的同一个实例加载的对象),你可以简单地使用:
if (context.ObjectStateManager.GetObjectStateEntry(myEntity).State == EntityState.Detached)
{
context.MyEntities.AddObject(myEntity);
}
// Attached object tracks modifications automatically
context.SaveChanges();
如果你可以使用任何关于对象键的知识,你可以使用这样的东西:
if (myEntity.Id != 0)
{
context.MyEntities.Attach(myEntity);
context.ObjectStateManager.ChangeObjectState(myEntity, EntityState.Modified);
}
else
{
context.MyEntities.AddObject(myEntity);
}
context.SaveChanges();
如果你不能通过Id判断对象是否存在,你必须执行查找查询:
var id = myEntity.Id;
if (context.MyEntities.Any(e => e.Id == id))
{
context.MyEntities.Attach(myEntity);
context.ObjectStateManager.ChangeObjectState(myEntity, EntityState.Modified);
}
else
{
context.MyEntities.AddObject(myEntity);
}
context.SaveChanges();
如果你知道你正在使用相同的上下文并且没有分离任何实体,你可以像这样创建一个通用版本:
public void InsertOrUpdate<T>(T entity, DbContext db) where T : class
{
if (db.Entry(entity).State == EntityState.Detached)
db.Set<T>().Add(entity);
// If an immediate save is needed, can be slow though
// if iterating through many entities:
db.SaveChanges();
}
Db当然可以是一个类字段,或者方法可以是静态的和一个扩展,但这是基本的。
使用Any检查现有行。
public static void insertOrUpdateCustomer(Customer customer)
{
using (var db = getDb())
{
db.Entry(customer).State = !db.Customer.Any(f => f.CustomerId == customer.CustomerId) ? EntityState.Added : EntityState.Modified;
db.SaveChanges();
}
}
Ladislav的答案很接近,但我不得不做了一些修改,以使其在EF6(数据库优先)中工作。我用我的AddOrUpdate方法扩展了我的数据上下文,到目前为止,这似乎与分离的对象工作得很好:
using System.Data.Entity;
[....]
public partial class MyDBEntities {
public void AddOrUpdate(MyDBEntities ctx, DbSet set, Object obj, long ID) {
if (ID != 0) {
set.Attach(obj);
ctx.Entry(obj).State = EntityState.Modified;
}
else {
set.Add(obj);
}
}
[....]
推荐文章
- c# vs Java Enum(适合c#新手)
- c#消毒文件名
- 在EF中更新父实体时如何添加/更新子实体
- ASP。NET身份的默认密码散列器-它是如何工作的,它是安全的?
- 如何写一个JSON文件在c# ?
- 静态隐式运算符
- 不区分大小写列表搜索
- 'throw'和'throw new Exception()'的区别
- 不能在lambda表达式中使用ref或out参数
- c# int到字节[]
- 将WPF组合框绑定到自定义列表
- foreach vs somlist . foreach (){}
- 为什么try{…}最后{…}好;尝试{…} catch{}坏?
- c# 8用多种情况切换表达式,结果相同
- 在没有事件源注册的情况下写入Windows应用程序事件日志