LINQ TO SQL我错过了一些明显的东西吗?

时间:2009-10-28 19:59:31

标签: c# .net linq linq-to-sql

我有这个方法,将从WCF客户端调用,但对于我的测试,我是一个本地“添加项目引用”。我收到的错误是我处理后无法调用DataContext。

    public IEnumerable<Server> GetServers()
    {
        // initialze to null
        ServersDataContext sdc = null;

        try
        {
            // get connected
            using (sdc = GetDataContext())
            {
                // disable this deferred loading
                sdc.DeferredLoadingEnabled = false;

                var relations = from svr in sdc.Servers; // complex linq here

                // return
                return relations;
            }
        }
        catch (Exception ex)
        {
            LogError(ex, "fwizs.Internal");
            throw;
        }
        finally
        {
            if (sdc != null)
            {
                sdc.Dispose();
            }
        }
    }

以下是我使用该方法的方法,它给出了这个错误:“无法访问已处置的对象。”

    if (da.GetServers()
        .Select(sv => sv.ServerID == s.ServerID).Count() == 0)
    {

        // do work since we found it
    }

对此返回的IEnumerable对象使用.Select()方法尝试运行回数据库以进行选择。在为WCF序列化后,我认为这不是一个问题,但我希望我的本地测试能够正常运行。

6 个答案:

答案 0 :(得分:4)

在方法中实现查询,以确保在处理数据上下文之前实际执行数据库调用。

var relations = from svr in sdc.Servers;

return relations.ToList();

答案 1 :(得分:4)

DeferredLoadingEnabled属性控制如何加载关系,而不是如何加载主数据。

您可以简单地使用ToList方法确保将数据加载到内存中:

return relations.ToList();

答案 2 :(得分:3)

LINQ是懒惰的,所以查询只在这里定义,而不是迭代。

那么,会发生什么是您定义查询,然后关闭datacontext。不久之后,您尝试迭代低谷,这意味着您尝试通过先前已关闭的SQL连接进行查询。

来自MSDN:

  

此方法使用延迟执行实现。立即返回值是一个对象,它存储执行操作所需的所有信息。在通过直接调用其GetEnumerator方法或在Visual C#中使用foreach或在Visual Basic中使用For Each来枚举对象之前,不会执行此方法表示的查询。

答案 3 :(得分:2)

当以这种方式使用时,

“using”关键字一旦超出范围就会保证处理的语法糖 - 这种情况发生在“返回关系”之后。

答案 4 :(得分:0)

您已使用using处理了您的datacontext 所以你不能在finally

中再次处理它

答案 5 :(得分:0)

除了其他人所说的关于使用.ToList的内容之外,这也应该有效,并且延迟执行:

public IEnumerable<Server> GetServers() {
    // initialze to null
    ServersDataContext sdc = null;
    try {
        // get connected
        using (sdc = GetDataContext()) {
            // disable this deferred loading
            sdc.DeferredLoadingEnabled = false;
            foreach (var relation in from svr in sdc.Servers) // complex linq here
                yield return relations;
        }
    }
    catch (Exception ex) {
        LogError(ex, "fwizs.Internal");
        throw;
    }
    finally {
        if (sdc != null) {
            sdc.Dispose();
        }
    }
}