Lad*_*nka 159
如果您正在使用附加对象(从上下文的同一实例加载的对象),您只需使用:
if (context.ObjectStateManager.GetObjectStateEntry(myEntity).State == EntityState.Detached)
{
context.MyEntities.AddObject(myEntity);
}
// Attached object tracks modifications automatically
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
如果您可以使用有关对象密钥的任何知识,您可以使用以下内容:
if (myEntity.Id != 0)
{
context.MyEntities.Attach(myEntity);
context.ObjectStateManager.ChangeObjectState(myEntity, EntityState.Modified);
}
else
{
context.MyEntities.AddObject(myEntity);
}
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
如果您无法通过其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();
Run Code Online (Sandbox Code Playgroud)
Erk*_* M. 32
从Entity Framework 4.3开始,AddOrUpdate
命名空间中有一个方法System.Data.Entity.Migrations
:
public static void AddOrUpdate<TEntity>(
this IDbSet<TEntity> set,
params TEntity[] entities
)
where TEntity : class
Run Code Online (Sandbox Code Playgroud)
由doc提供:
调用SaveChanges时,按键添加或更新实体.相当于数据库术语的"upsert"操作.使用迁移为播种数据时,此方法非常有用.
要回答@ Smashing1978的评论,我将粘贴@Colin提供的链接中的相关部分
AddOrUpdate的工作是确保在开发期间为数据设定种子时不创建重复项.
首先,它将在您的数据库中执行查询,查找记录,其中您作为键提供的任何内容(第一个参数)与AddOrUpdate中提供的映射列值(或多个值)相匹配.所以这对于匹配来说有点松散 - 但是对于播种设计时间数据来说非常好.
更重要的是,如果找到匹配项,则更新将全部更新并清除AddOrUpdate中没有的任何内容.
也就是说,我有一种情况,我从外部服务中提取数据,并通过主键插入或更新现有值(我的本地数据为消费者是只读的) - 现在已经AddOrUpdate
在生产中使用超过6个月了远没有问题.
如果您知道您使用相同的上下文而不是分离任何实体,则可以创建如下通用版本:
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();
}
Run Code Online (Sandbox Code Playgroud)
db
当然可以是一个类字段,或者可以将方法设为静态和扩展,但这是基础知识.
召唤时会发生魔力,SaveChanges()
并取决于当前的情况EntityState
.如果实体有EntityState.Added
,它将被添加到数据库中,如果它有EntityState.Modified
,它将在数据库中更新.所以你可以实现InsertOrUpdate()
如下方法:
public void InsertOrUpdate(Blog blog)
{
using (var context = new BloggingContext())
{
context.Entry(blog).State = blog.BlogId == 0 ?
EntityState.Added :
EntityState.Modified;
context.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您无法检查Id = 0
以确定它是否是新实体,请查看Ladislav Mrnka的答案.
使用 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();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
144208 次 |
最近记录: |