由于没有任何方法可以在当前最新的EF版本中为实体添加唯一约束,我提出了一个想法。 (我知道可以通过嵌入SQL来添加约束)
我在Repository类中添加了一个方法:
private IDbSet<T> Entities;
public virtual bool Contains(Func<T, bool> predicate)
{
return Entities.Any(t => predicate(t));
}
我认为这将取代我目前的重复预防逻辑:
bool already exists = (from t in someSet.Entities
where t.UniqueColumn == entity.UniqueColumn select t).
FirstOrDefault() != null;
if(alreadyExists)
throw new Exception("Entity already exists in DB.");
这是一个好主意,防止重复插入/更新数据库的最佳方法是什么?
编辑:我编辑了Contains方法以使用谓词。现在我可以编写这样的代码:
if(repository.Contains(t=> t.Email == "someemail@email.com")
throw new Exception("Email already exists.");
答案 0 :(得分:3)
如果这种情况很少见,那么在数据库上放置一个唯一约束然后捕获尝试插入现有记录时生成的异常就没有错。
如果这可能发生很多,那么我仍然会将约束放在数据库上,但要按原样进行检查。
FWIW,您应该使您的方法采用Expression<Func<T, bool>>
,以便查询不会转换为Enumerable。
答案 1 :(得分:2)
嗯,这不起作用,因为您需要声明要强制执行唯一性的内容。在主键上?在像“UserName”这样的其他专栏上?在User.EMail列上,但仅当它不为null时(因此您可以同时拥有多个具有空电子邮件的用户)?
我更喜欢这些事情是明确的。所以我实际上更喜欢你之前的逻辑。
答案 2 :(得分:0)
在数据库中强制实施唯一性的最佳方法是使用唯一约束。