什么是最有效的方法来实现更新行,如果它存在,否则插入新的行逻辑使用实体框架?或者这有什么规律吗?
当前回答
如果你正在使用附加对象(从上下文的同一个实例加载的对象),你可以简单地使用:
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();
其他回答
神奇的是在调用SaveChanges()时发生的,这取决于当前的EntityState。如果实体有一个EntityState。如果它有一个EntityState,那么它将被添加到数据库中。修改后,将在数据库中更新。所以你可以实现InsertOrUpdate()方法,如下所示:
public void InsertOrUpdate(Blog blog)
{
using (var context = new BloggingContext())
{
context.Entry(blog).State = blog.BlogId == 0 ?
EntityState.Added :
EntityState.Modified;
context.SaveChanges();
}
}
更多关于EntityState的信息
如果你不能检查Id = 0来确定它是否是一个新实体,请检查Ladislav Mrnka的答案。
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();
}
}
从实体框架4.3开始,在命名空间System.Data.Entity.Migrations中有一个AddOrUpdate方法:
public static void AddOrUpdate<TEntity>(
this IDbSet<TEntity> set,
params TEntity[] entities
)
where TEntity : class
医生说:
在调用SaveChanges时按键添加或更新实体。等效 到数据库术语中的“upsert”操作。此方法可以是 在使用迁移播种数据时很有用。
为了回答@Smashing1978的评论,我将从@Colin提供的链接中粘贴相关部分
The job of AddOrUpdate is to ensure that you don’t create duplicates when you seed data during development. First, it will execute a query in your database looking for a record where whatever you supplied as a key (first parameter) matches the mapped column value (or values) supplied in the AddOrUpdate. So this is a little loosey-goosey for matching but perfectly fine for seeding design time data. More importantly, if a match is found then the update will update all and null out any that weren’t in your AddOrUpdate.
也就是说,我有一种情况,我从外部服务中提取数据,并通过主键插入或更新现有值(并且我的消费者本地数据是只读的)-在生产中使用AddOrUpdate已经超过6个月了,到目前为止没有问题。
插入else更新
public void InsertUpdateData()
{
//Here TestEntities is the class which is given from "Save entity connection setting in web.config"
TestEntities context = new TestEntities();
var query = from data in context.Employee
orderby data.name
select data;
foreach (Employee details in query)
{
if (details.id == 1)
{
//Assign the new values to name whose id is 1
details.name = "Sanjay";
details. Surname="Desai";
details.address=" Desiwadi";
}
else if(query==null)
{
details.name="Sharad";
details.surname=" Chougale ";
details.address=" Gargoti";
}
}
//Save the changes back to database.
context.SaveChanges();
}
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?
- 如何分裂()一个分隔字符串到一个列表<字符串>
- 如何转换列表<字符串>列表<int>?
- c#对象列表,我如何得到一个属性的和