2012-03-13 60 views
2

为一个项目编写DLL,我刚刚开始使用LINQ to SQL,并将所有方法移到这个新的dll后。我disovered因为它被布置我不能接取的DataContext,我明白为什么,但我不知道我怎样才能接取查询的结果我的主要项目方法这样:在DLLLINQ to SQL在DataContext之后使用查询Dispose

public static IEnumerable<Problem> GetProblemsNewest(int howMuch) 
     { 
      using (ProblemClassesDataContext context = new ProblemClassesDataContext()) 
      { 
       var problems = (from p in context.Problems orderby p.DateTimeCreated select p).Take(howMuch); 

       return problems; 
      } 
     } 

我的方法

调用它:

IEnumerable<Problem> problems = ProblemsManipulation.GetProblemsNewest(10); 
//Error can't acess it because it was disposed.. 

这仅仅是第一种方法,我有较大的所以我真的需要一种方法来做到这一点。在DLL中必须有一种使用LINQ to SQL的方法?我知道我可以做点像.ToList.ToArray,但是我不能直接访问行属性,并且不得不引用它作为问题[0],问题[1]等,这比起调用主项目中的代码。

回答

7

在使用语句之外,上下文自动处理,所以当IEnumerable实际枚举时,上下文已经处理完毕。

因此,您需要告诉Linq它应该继续,并实际检索DB中的值,而您的using声明中。您可以通过ToList()ToArray(或其他)进行此操作。

查看更新的代码:

public static IList<Problem> GetProblemsNewest(int howMuch) 
{ 
    using (ProblemClassesDataContext context = new ProblemClassesDataContext()) 
    { 
     var problems = (from p in context.Problems orderby p.DateTimeCreated select p).Take(howMuch); 

     return problems.ToList(); 
    } 
} 
+0

所以我应该只写方法将其置于dll中,并在Im完成主项目中的第一个方法后调用它? – formatc 2012-03-13 20:39:53

+0

不,上下文并不意味着存在更长的时间,而是使用建议的解决方案 – ntziolis 2012-03-13 20:42:08

1

你可以通过退出使用块之前做对了IEnumerable一个.ToList()处理它。这将检索记录并填充列表。根据您的方案在性能方面,这可能不是最优的,但(你输了懒惰的检索和查询的附加过滤的可能性)

4

更改此:

return problems; 

这样:

return problems.ToList(); 

说明

的ToList()会遍历这些结果,和他们拉人l进入内存。因为这发生在using语句中,所以你很好。而且因为它创建了一个列表,所以你的值将被返回。

你可以用其他方法做到这一点。基本的想法是在using语句关闭之前实际检索结果。

另一种解决方案是避免使用using语句,创建一个拥有该对象的迭代器,并在最后一项迭代完成时对其进行处置。

1

你必须完成所使用的子句内的查询,即使用ToList()或第()或Count(),等...

0

你可能不希望使用在使用范围内;那么问题在于你以后不能使用导航属性,因为当你尝试加载相关数据时,你会遇到同样的“处理对象”问题。你需要做的是让上下文存在,并直接返回结果。或者,当您返回结果时,请致电ToList(),稍后查询所有相关数据。

1

目前在返回查询,当你想使用它,因为数据库连接您的使用之前关闭,你会得到一个异常,只是做:

return problems.AsEnumerable() 

这是因为deffered execution方式LINQ的。实际上,您的problems对象只是查询,您应该将其转换为对象以在其他地方使用它。