LinqToSql奇怪的行为 [英] LinqToSql strange behaviour

查看:107
本文介绍了LinqToSql奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:


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);



其中,标记列表与LT;标签> - 由构造器创建标签列表,所以他们没有身份证。
我运行该代码把一个brakepoint上符合调试和等待几个周期去了。然后,我把tagToPosts.ToList()在监视窗口查询来执行。
在SQL事件探查器,我可以看到下面的查询:

where tags is a List<Tag> - list of tags created by constructor, so they have no id. I run the the code putting a brakepoint on line with Debug and wait for a few cycles to go. Then I put tagToPosts.ToList() in the Watch window for query to execute. In SQL profiler I can see the following query:

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'

我们可以看到每一个参数的参数有最后的值 tag.Name 在一个周期。
你有没有关于如何得到这个AROUT并得到循环添加其中,新情况每Tyme的任何想法?我可以看到的IQueryable存储执行之前唯一的指向变量。

We can see every parameter parameter have the value of last tag.Name in a cycle. Have you any idea on how to get arout this and get cycle to add Where with new condition every tyme? I can see IQueryable stores only pointer to variable before execution.

推荐答案

更改的foreach 来:

foreach (Tag tag in tags){
    var x = tag.Name;
    tagToPosts = tagToPosts.Where(t => t.Name != x);
}



这背后的原因是懒惰的评价和可变捕获。基本上,你在做什么在的foreach 语句的的滤除结果,因为它可能看起来像。要构建一个表达式树取决于一些变量来执行。需要注意的是实际的变量在拍摄时在表达式树抓获,而不是他们的价值观是非常重要的。由于变量标记用于每一次(和它的范围是整个的foreach ,这样就不会熄灭在每个迭代结束)的范围,它的捕获表达式的每一个部分,最后的值将用于<青霉>所有的其出现的。该解决方案是使用该范围内的一个临时变量的在foreach 的所以它会走出去的范围在每次迭代和它的下一次迭代,它会被认为是一个新变量

The reason behind this is lazy evaluation and variable capturing. Basically, what you are doing in the foreach statement is not filtering out results as it might look like. You are building an expression tree that depends on some variables to execute. It's important to note that the actual variables are captured in that expression trees, not their values at the time of capture. Since the variable tag is used every time (and it's scope is the whole foreach, so it won't go out of scope at the end of each iteration), it's captured for every part of the expression and the last value will be used for all of its occurrences. The solution is to use a temporary variable which is scoped in the foreach so it'll go out of scope at each iteration and it the next iteration, it'll be considered a new variable.

这篇关于LinqToSql奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆