Linq to SQL:查询不查看未完成的更改
跟进至this question。我有以下代码:Linq to SQL:查询不查看未完成的更改
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,它不会。
我可以让它看看待处理的更改以及表中已有的内容吗?
我不认为这是可能的一般。想象一下,你犯了一个这样的查询:
dataContext.Users.InsertOnSubmit(new User { GroupId = 1 });
var groups = dataContext.Groups.Where(grp => grp.Users.Any());
数据库一无所知新用户(还),因为插入尚未COMMITED,所以生成的SQL查询可能无法与ID = 1返回集团。 DataContext在这种情况下可以考虑尚未提交的插入的唯一方法是获取整个组表(如果它们受到查询影响,可能还有更多表),并在客户端上执行查询,这当然是不可取的。我想L2S设计师认为,如果一些查询考虑到尚未提交的插入而另一些则不考虑,这将违反直觉,所以他们选择不考虑它们。
你为什么不使用类似
foreach (var name in names.Distinct(StringComparer.InvariantCultureIgnoreCase))
进入数据库之前过滤掉重复的名字?
你为什么不尝试这样
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;
}
}
因为'名称'可能还包含“Alice”和“Chuck”。为了简洁,我只是将它们排除在外。 – 2009-10-30 14:50:04
我很抱歉,我不明白的LINQ to SQL一样多。
但是,当我看代码时,它似乎告诉它使用SubmitChanges
一次插入所有记录(类似于事务),并且您试图从数据库中检查它的存在,记录是而不是插入。
编辑:尝试将SubmitChanges
放入循环中,看看代码将按照您的期望运行。
将SubmitChanges放入循环内会导致数据库的额外往返。这是不可取的。 – 2009-10-30 14:50:35
您可以查询相应ChangeSet
集合,如
if(
dataContext.Users.
Union(dataContext.GetChangeSet().Inserts).
Except(dataContext.GetChangeSet().Deletes).
SingleOrDefault(u => u.Name.ToUpper() == s.ToUpper()) == null)
这将创建在用户表和未决插入值的联合,将排除挂起删除。
当然,您可能需要创建一个changeSet
变量以防止多次调用GetChangeSet
函数,并且您可能需要适当地将集合中的对象转换为适当的类型。在“插入和删除”集合中,您可能想要使用类似的方式对其进行过滤
...GetChangeSet().Inserts.Where(o => o.GetType() == typeof(User)).OfType<User>()...
我不能使用names.Distinct,因为名称(在我的真实代码中)也是来自另一个数据库的Linq-to-SQL查询。但是我关于L2S在一般情况下无法做到这一点的事实表明您的观点。 – 2009-10-30 14:49:20
@Roger:如果你想枚举所有的名字,你必须从数据库中获取整个集合,所以为什么不使用.ToList()来获取它们并在生成的Linq-To-Objects列表上使用.Distinct ? – Niki 2009-10-30 15:05:58