如何从单个变量中的循环中保存多个linq查询?

时间:2012-10-04 18:28:54

标签: c# asp.net sql linq

我认为可以从单个变量中的循环中保存多个linq查询吗?

public ActionResult Index()
    {
        string ActiveUserId = (string)Session["ActiveUserGuid"];
        Guid MyGuid = new Guid(ActiveUserId);

        var queryRoots = from r in db.Roots
                         where r.UserId == MyGuid
                         select r.TaskId;

//Here is the questionable Part
        foreach (var i in queryRoots)
        {             
            var queryAllTasks = from t in db.Tasks
                                join b in db.Trees on t.TaskId equals b.ChildId
                                where b.TaskId == i
                                select t;
            tasksForView.Add(queryAllTasks); <---????? obviously doesnt work
        };

        return View(queryAllTasks);
    }

public class Root
{
    public int RootId { get; set; }

    public Guid UserId { get; set; }
    public User User { get; set; }  //navigation Property

    public int TaskId { get; set; } // composite key
    public int ChildId { get; set; }
    public Tree Tree { get; set; } //navigation Property
}

public class Tree
{
    public int TaskId { get; set; }
    public int ChildId { get; set; }
    public int Length { get; set; } //Path length

    public virtual ICollection<Root> Roots { get; set; }

}

如果你想知道它应该做什么。我想从分层转换闭包表中查询几个子树并将它们返回到视图。

我知道我的代码并不接近工作,我只是尝试了非常简单的解决方案! 我想以不同的方式进行查询可以解决所有问题

3 个答案:

答案 0 :(得分:2)

在整数列表中使用Contains

var tasks = 
    from t in db.Tasks
    join b in db.Trees on t.TaskId equals b.ChildId
    where queryRoots.Contains(b.TaskId)
    select t;

return View(tasks);

或在一个查询中完成所有操作:

var tasks = 
    from t in db.Tasks
    join b in db.Trees on t.TaskId equals b.ChildId
    join r in db.Roots on r.TaskId equals b.TaskId
    where r.UserId == MyGuid
    select t;

return View(tasks);

答案 1 :(得分:0)

这里的问题是你closing over the loop variable。 LINQ查询尽可能使用延迟执行,因此您只需定义查询的内容并存储它,而不是计算结果并存储它们。

你有几个选择。您只需在查询末尾添加ToList即可;它会急切地评估它,存储该列表不会导致问题。

您的查询正在使用i,这在循环中会发生变化。由于查询实际上并未在循环结束之后评估i是什么,因此i将始终具有最后一个值。只需在循环内添加一个新的局部变量并为其分配i,就可以轻松解决这个问题。在查询中使用该局部变量。

答案 2 :(得分:0)

正如其他人所说,queryAllTasks在循环的每次迭代中都延迟执行。所以你要存储的只是IQueryable

你想要的是

tasksForView.Add(queryAllTasks.ToList());

另外,我注意到您尝试将queryAllTasks作为视图模型返回,但该变量的范围限定为for循环。我假设你想要返回tasksForView作为你的模型(我进一步假设在其他地方宣布,因为我在你提供的代码中没有看到它的声明。)