gpt4 book ai didi

c# - LinqToSql 奇怪的行为

转载 作者:行者123 更新时间:2023-11-30 13:29:30 24 4
gpt4 key购买 nike

我有以下代码:


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

哪里tagsList<Tag> - 构造函数创建的标签列表,因此它们没有 ID。我运行代码,将制动点与 Debug 联机,然后等待几个周期结束。然后我将 tagToPosts.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'

我们可以看到每个参数参数的值都是最后tag.Name在一个循环中。你知道如何解决这个问题并获得周期来添加 Where每次都有新的情况?我可以看到 IQueryable 在执行前只存储指向变量的指针。

最佳答案

将您的 foreach 更改为:

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

这背后的原因是惰性评估和变量捕获。基本上,您在 foreach 语句中所做的是不是过滤掉可能看起来像的结果。您正在构建一个依赖于某些要执行的变量的表达式树。重要的是要注意实际变量是在该表达式树中捕获的,而不是它们在捕获时的值。由于每次都使用变量tag(而且它的作用域是整个foreach,所以它不会在每次迭代结束时超出作用域),它被捕获对于表达式的每个部分和最后一个值将用于其出现的所有。解决方案是使用 foreach 范围内的临时变量,这样它会在每次迭代时超出范围,在下一次迭代时,它将被视为一个新变量.

关于c# - LinqToSql 奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/658818/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com