实体框架核心添加如果不存在
我使用此代码
using Microsoft.EntityFrameworkCore.ChangeTracking;
public static class DbSetExtensions
{
public static EntityEntry<T> AddIfNotExists<T>(this DbSet<T> dbSet, T entity, Expression<Func<T, bool>> predicate = null) where T : class, new()
{
var exists = predicate != null ? dbSet.Any(predicate) : dbSet.Any();
return !exists ? dbSet.Add(entity) : null;
}
}
,并且
var purchase = new Models.Purchase();
var trackingnumber= "222";
_context.Purchases.AddIfNotExists(purchase, p => p.BankTrackingNum == trackingnumber);
await _context.SaveChangesAsync();
“在写入之前阅读”可以违反数据完整性而不会放入交易控制中。
在SQL Server中,我们可以使用Merge语句。但是,EF中没有合并语句。 您还知道交易以外的解决方案吗?
I use this code
using Microsoft.EntityFrameworkCore.ChangeTracking;
public static class DbSetExtensions
{
public static EntityEntry<T> AddIfNotExists<T>(this DbSet<T> dbSet, T entity, Expression<Func<T, bool>> predicate = null) where T : class, new()
{
var exists = predicate != null ? dbSet.Any(predicate) : dbSet.Any();
return !exists ? dbSet.Add(entity) : null;
}
}
and
var purchase = new Models.Purchase();
var trackingnumber= "222";
_context.Purchases.AddIfNotExists(purchase, p => p.BankTrackingNum == trackingnumber);
await _context.SaveChangesAsync();
“Read before write” can violate data integrity without being put inside a transaction control.
In SQL Server, we can use merge statement. but merge statement is not available in EF.
Do you know the solution other than transactions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这实际上是做到这一点的正确方法,钥匙的唯一性将从持久层中到达(并得到验证)。
您的“阅读之前阅读”根本不会引起任何问题,但是“在阅读和尝试写作时,另一个写作”会导致问题。
这是做到这一点的正确方法,您甚至可以将支票丢弃,因为DB总是会扔掉,并且只是故意处理“重复键”例外,只需确保有适当的约束即可。
对于主要问题,除非您分发锁定代码(假设您控制所有呼叫),则不能做太多。种族条件是真实的事情,但不太可能发生。
This is actually the proper way to do it, uniqueness of the key will come ( and be validated ) from the persistence layer.
Your "read before write" can cause no problem at all, but "an other's write while you read and try to write" would cause an issue.
This is the proper way to do it, you could even throw the check away since the db will always throw, and just handle the "duplicate key" exceptions on purpose, just make sure proper constraints are in place.
For the main problem you can not do much unless you distribute-lock the code ( assuming you control all calls ). Race conditions are a real thing but not likely to happen.