跟进this question。我有以下代码:
string[] names = new[] { "Bob", "bob", "BoB" };
using (MyDataContext dataContext = new MyDataContext())
{
foreach (var name in names)
{
string s = name;
if (dataContext.Users.SingleOrDefault(u => u.Name.ToUpper() == s.ToUpper()) == null)
dataContext.Users.InsertOnSubmit(new User { Name = name });
}
dataContext.SubmitChanges();
}
...它会插入所有三个名称(“Bob”,“bob”和“BoB”)。如果这是Linq-to-Objects,那就不会。
我可以查看待处理的更改以及表中已有的更改吗?
答案 0 :(得分:2)
我认为这不可能。想象一下,你做了这样的查询:
dataContext.Users.InsertOnSubmit(new User { GroupId = 1 });
var groups = dataContext.Groups.Where(grp => grp.Users.Any());
数据库对新用户一无所知(因为插件尚未提交),因此生成的SQL查询可能不会返回Id = 1的组.DataContext可以考虑的唯一方法是 - 在这种情况下提交插入将是获取整个Groups-Table(如果它们受查询影响,可能还有更多表)并在客户端上执行查询,这当然是不可取的。我想L2S设计师认为,如果某些查询考虑到尚未提交的插入而其他人不这样做,则会违反直觉,因此他们选择不考虑它们。
为什么不使用
之类的东西foreach (var name in names.Distinct(StringComparer.InvariantCultureIgnoreCase))
在点击数据库之前过滤掉重复的名称?
答案 1 :(得分:1)
为什么不尝试这样的事情
foreach (var name in names)
{
string s = name;
if (dataContext.Users.SingleOrDefault(u => u.Name.ToUpper() == s.ToUpper()) == null)
{
dataContext.Users.InsertOnSubmit(new User { Name = name });
break;
}
}
答案 2 :(得分:0)
对不起,我不太了解LINQ to SQL。
但是,当我查看代码时,似乎您告诉它使用SubmitChanges
一次插入所有记录(类似于事务),并且您正试图从DB检查它是否存在,当记录完全不时。
编辑:尝试将SubmitChanges
放入循环中,看看代码是否按照您的预期运行。
答案 3 :(得分:0)
您可以查询相应的ChangeSet
集合,例如
if(
dataContext.Users.
Union(dataContext.GetChangeSet().Inserts).
Except(dataContext.GetChangeSet().Deletes).
SingleOrDefault(u => u.Name.ToUpper() == s.ToUpper()) == null)
这将在Users表和待处理的插入中创建值的并集,并将排除挂起的删除。
当然,您可能希望创建一个changeSet
变量以防止多次调用GetChangeSet
函数,并且您可能需要将集合中的对象适当地转换为适当的类型。在“插入和删除”集合中,您可能希望使用类似
...GetChangeSet().Inserts.Where(o => o.GetType() == typeof(User)).OfType<User>()...