我有这个方法,将从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序列化后,我认为这不是一个问题,但我希望我的本地测试能够正常运行。
答案 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();
}
}
}