2017-08-10 106 views
0

假设我有两个实体E1E2都共享相同的Code值。假设我想删除第一和插入下一个:使用实体框架删除和插入实体

Item.Delete(E1); 
Item.Insert(E2); 
Item.Save(); 

public void Delete(Entity E) 
{ 
    var existingEntity = _context.EntityTable.SingleOrDefault(s => s.Code == E.Code); 
    _context.EntityTable.Remove(existingEntity); 
} 

public void Insert(Entity E) 
{ 
    var existingEntity = _context.EntityTable.FirstOrDefault(s => s.Code == E.Code); 
    if (existingEntity != null){ 
     throw new ArgumentException("Item alread exists.") 
    } 

    var newEntity = CreateDbEntity(E); // Create Db Entity just convert the type. Nothing much here. 
    _context.EntityTable.Add(newEntity); 
} 

public void Save() 
{ 
    _context.SaveChanges(); 
} 

这里的问题是,当我在_contextEntityTable删除E1,即不会立即反映到我保存。因此,操作将失败,因为E1仍然存在,插入E2不成功。有没有解决这个问题,EntityTable确实反映了所做的更改?

+1

为什么你不把独特的条件留给SQL而不检查代码? –

+0

在您查询是否存在以及您对SaveChanges()的调用之间,还可以通过另一个进程或线程插入。不要在代码中这样做。 – CodeCaster

+0

删除>保存>插入>保存..大声笑 – niksofteng

回答

0

它看起来像你只是有一个操作顺序错误这可能不是最有效的方式,但它应该照顾你的问题。

Item.Delete(E1); 
Item.Save(); 
Item.Insert(E2); 
Item.Save(); 

以该顺序调用它们。

或者您可以将save方法添加到您的删除和插入方法中,以便它可以保存每个方法,您只需使用两行。

public void Delete(Entity E) 
{ 
    var existingEntity = _context.EntityTable.SingleOrDefault(s => s.Code == E.Code); 
    _context.EntityTable.Remove(existingEntity); 
    Save() 
} 

public void Insert(Entity E) 
{ 
    var existingEntity = _context.EntityTable.FirstOrDefault(s => s.Code == E.Code); 
    if (existingEntity != null){ 
     throw new ArgumentException("Item alread exists.") 
    } 

    var newEntity = CreateDbEntity(E); // Create Db Entity just convert the type. Nothing much here. 
    _context.EntityTable.Add(newEntity); 
    Save() 
} 

public void Save() 
{ 
    _context.SaveChanges(); 
} 

,然后你可以这样调用它

Item.Delete(E1); 
Item.Insert(E2); 

希望这有助于!如果不让我知道,我会删除答案(我不得不使用答案,因为我不能评论50代表,否则我会在回答之前使用评论来获得更清晰的答案)干杯!

+0

谢谢。总的来说问题是我想避免两次去DB。我为Repo使用UOW模式,以便业务逻辑对象不需要多次访问数据库以插入不同的对象。 – Husain

1

每次操作后简单呼叫SaveChanges

你想进行交易,当你初始化你的背景下(这样可以确保这两个操作都执行):然后

_context = new FooEntities(); 
_transaction = _context.Database.BeginTransaction(); 

Save方法将提交替代交易:

_transaction.Commit(); 

它将不会损害处理上下文和交易,但我相信你已经这样做了;)


在一个侧面说明,因为你扔反正异常:

if (existingEntity != null){ 
    throw new ArgumentException("Item alread exists.") 
} 

为什么不能创造的Code列unique constraint?这样数据库会抛出异常;)

+0

谢谢。我试图避免为此往返两次DB。唯一的约束条件适用于这个简单的例子,但不适用于我的情况,因为我有一个软删除。有了这个约束,我将不得不解密从数据库中获得的异常,以便向API用户返回有用的消息。 – Husain

+0

您可以在多列(例如Code&IsDeleted)之上设置uniuqe限制。使用[ExceptionFilters](https://stackoverflow.com/a/34813242/2441442),使用C#6可以轻松实现更好的异常。关于往返:典型的阅读是昂贵的阅读,因为这比写作发生得多; @Husain –