LINQ to SQL调用存储过程

时间:2009-10-13 16:01:46

标签: c# asp.net linq

我创建了一个小型测试Web应用程序,它使用LINQ to SQL。我有ObjectDataSource和GridView。 GridView的Datasource是ObjectDataSource。现在,这个ObjectDataSource使用一个名为MyTasks的类(如下所述的方法名称:GetAllTask​​s())来填充SQL中使用Linq to SQL的Tasks表中的所有任务。它调用存储过程GetAllMyTasks()。

我有以下方法,它完美无缺。

 public static IEnumerable<GetAllMyTasksResult> GetAllTasks()
{
    MyTasksDataContext db = new MyTasksDataContext();
    var tasks = db.GetAllMyTasks().Select(x => x);
    return tasks;
}

现在,如果我尝试用以下代码替换上面的代码,只是为了利用关键字来创建Disposable MyTasksDataContext对象。它给我一个错误,说“读取器关闭时无效尝试调用读取”。我在这里缺少什么。

 public static IEnumerable<GetAllMyTasksResult> GetAllTasks()
{
    using (MyTasksDataContext db = new MyTasksDataContext())
    {
        var tasks = db.GetAllMyTasks().Select(x => x);
        return tasks;
    }
}

任何人都可以告诉我这背后的理由吗?我知道我的MyTasksDataContext对象正在调用它的dispose方法。

2 个答案:

答案 0 :(得分:10)

使用ToList()扩展方法尽早评估枚举。

public static IEnumerable<GetAllMyTasksResult> GetAllTasks()
{
    using (MyTasksDataContext db = new MyTasksDataContext())
    {
        return db.GetAllMyTasks().ToList();
    }
}

这将导致枚举发生在使用中,而不是在处理连接之后。

枚举需要在'using'块中发生的原因是LINQ使用了一种叫做'延迟执行'的东西,以便进行更强大的查询编写。

例如,如果您希望通用函数执行分页,则可以将.Skip(30).Take(10)附加到结果的末尾,并且可以将该逻辑烘焙到生成的SQL中。

PS:
你说:

  

我知道我的MyTasksDataContext   object正在调用它的dispose方法。

这是假的。

'using'块正在调用Dispose方法,而不是对象本身。而且,由于写了使用,正在调用Dispose

答案 1 :(得分:3)

正如John Gietzen所提到的,ToList()将解决您的直接问题。

这是必要的原因是因为延迟执行。在迭代查询之前,LINQ通常不会执行任何操作。 LINQ to SQL将调用存储过程,但不会从结果中读取行,直到迭代查询。