1

为什么没有触发异常?Linq 的“Any()”不考虑新条目?

MyContext db = new MyContext();

foreach (string email in {"asdf@gmail.com", "asdf@gmail.com"})
{
   Person person = new Person();
   person.Email = email;

   if (db.Persons.Any(p => p.Email.Equals(email))
   {
       throw new Exception("Email already used!");
   }

   db.Persons.Add(person);
}

db.SaveChanges()

不应该在第二次迭代时触发异常吗?

前面的代码适用于该问题,但实际情况如下:
我收到一个人的 excel,我对其进行迭代,将每一行作为一个人添加到 db.Persons,检查他们的电子邮件尚未在 db 中使用. 问题是当工作表本身中有重复的电子邮件时(两行具有相同的电子邮件)

4

3 回答 3

1

调用db.Persons总是会触发数据库查询,但这些新的 Persons 尚未持久化到数据库中。

于 2013-11-12T16:41:13.383 回答
1

是 - 查询(按设计)仅针对数据源计算。如果要查询内存中的项目,还可以查询Local存储:

if (db.Persons.Any(p => p.Email.Equals(email) || 
    db.Persons.Local.Any(p => p.Email.Equals(email)  )

但是 - 由于您可以控制添加到商店的内容,因此检查代码中的重复项而不是 EF 中的重复项是否有意义?或者这只是一个人为的例子?

此外,为已经存在的项目抛出异常似乎也是一个糟糕的设计 - 异常可能很昂贵,如果客户端不知道捕获它们(在这种情况下比较异常的消息),它们可能会导致整个程序意外终止。

于 2013-11-12T16:42:59.407 回答
0

我想如果你在调试中查看数据,你会发现新人在第二次迭代中不存在。如果你要再次设置 MyContext db = new MyContext() ,它会是,但你不会在真实情况下这样做。

您需要解决的实际用例是什么?这个例子似乎不会在真实情况下发生。

如果您要与数据库进行比较,您的代码应该可以工作。如果您需要防止重复输入,它应该发生在其他地方 - 在客户端上或在开始将其写入数据库之前检查 C# 集合。

于 2013-11-12T16:37:33.240 回答