Dmy*_*nko 3 c# linq lambda linq-to-sql
我有以下代码:
var tagToPosts = (from t2p in dataContext.TagToPosts
join t in dataContext.Tags on t2p.TagId equals t.Id
select new { t2p.Id, t.Name });
//IQueryable tag2postsToDelete;
foreach (Tag tag in tags)
{
Debug.WriteLine(tag);
tagToPosts = tagToPosts.Where(t => t.Name != tag.Name);
}
IQueryable tagToPostsToDelete = (from t2p in dataContext.TagToPosts
join del in tagToPosts on t2p.Id equals del.Id
select t2p);
dataContext.TagToPosts.DeleteAllOnSubmit(tagToPostsToDelete);
Run Code Online (Sandbox Code Playgroud)
where tags是List<Tag>- 构造函数创建的标签列表,因此它们没有id.我运行代码将一个刹车点放在Debug上,然后等待几个周期.然后我将WatchToPosts.ToList()放在Watch窗口中以便执行查询.在SQL事件探查器中,我可以看到以下查询:
exec sp_executesql N'SELECT [t0].[Id], [t1].[Name]
FROM [dbo].[tblTagToPost] AS [t0]
INNER JOIN [dbo].[tblTags] AS [t1] ON [t0].[TagId] = [t1].[Id]
WHERE ([t1].[Name] @p0) AND ([t1].[Name] @p1) AND ([t1].[Name] @p2)',N'@p0 nvarchar(4),@p1 nvarchar(4),@p2 nvarchar(4)',@p0=N'tag3',@p1=N'tag3',@p2=N'tag3'
Run Code Online (Sandbox Code Playgroud)
我们可以看到每个参数参数tag.Name在一个循环中都具有last的值.你有没有想过如何获得这个,并获得Where每个tyme 添加新条件的周期?我可以看到IQueryable只在执行之前存储指向变量的指针.
Meh*_*ari 11
将您更改foreach为:
foreach (Tag tag in tags){
var x = tag.Name;
tagToPosts = tagToPosts.Where(t => t.Name != x);
}
Run Code Online (Sandbox Code Playgroud)
这背后的原因是懒惰的评估和变量捕获.基本上,您在foreach语句中所做的不是过滤掉可能看起来像的结果.您正在构建一个依赖于要执行的某些变量的表达式树.重要的是要注意实际变量是在表达式树中捕获的,而不是捕获时的值.由于变量tag每次使用(和它的范围是整个foreach,所以它不会超出范围在每次迭代结束),它捕获的表达和最后一个值的每个部分将被用于所有的它的发生.解决方案是使用一个临时变量,该变量在foreach中作用域因此它会在每次迭代时超出范围,并且在下一次迭代时,它将被视为一个新变量.
| 归档时间: |
|
| 查看次数: |
3062 次 |
| 最近记录: |