我通过linq到sql模拟链接服务器上的连接。我的问题是,似乎linqtosql将y.Xstatuses的所有行都带入内存然后进行连接。 如果这是真的,我如何将所有内存保留在sql server上(并且仍然执行交叉数据文本连接操作),如果这不正确,那会是吃掉我所有的ram吗?
var x = new fooDataContext();
var y = new barDataContext();
var allXNotDeleted = (from w in x.CoolTable
where x.IsDeleted != false).ToList();//for our demo this returns 218 records
var allXWithCompleteStatus = (from notDeleted in allXNotDeleted
join s in y.XStatuses on notDeleted.StatusID equals s.StatusID
where s.StatusID == 1
select notDeleted).Tolist();// insert massive memory gobbler here
return allXwithCompleteStatus;
编辑: 试图实现Kevinbabcock的想法
using (x = new fooDataContext())
using (var y = new barDataContext())
{
var n = (from notDeleted in x.GetTable<CoolTable>()
join z in y.GetTable<Xstatus>() on x.StatusID equals z.StatusID
where z.StatusID == 1 and x.IsDeleted != false
select x).ToList();
}
这仍然会引发跨上下文查询异常
答案 0 :(得分:3)
无法直接在数据库上执行跨数据上下文查询。 在内存中获取记录集之一(ToList())强制其他联接在内存中处理。
如果要在sql server上执行所有操作,则必须将每个实体放在同一个DataContext中。
答案 1 :(得分:0)
我建议不要在 ToList
上致电allXNotDeleted
作为开始。这会将这些记录拉入内存,这可能意味着当您执行第二次查询时,无法避免将所有其他数据拉入内存。
编辑:
另外请注意,如果表格特别大,并且只需要几列中的数据,则可以在数据库对象模型中将 Delay Loaded
设置为True
对于你不需要的列。
EDIT2:
我刚刚注意到这两个查询来自不同的上下文。在这种情况下,我建议您创建一个存储过程并从其中一个上下文调用它。 sproc应该负责跨越上下文。
答案 2 :(得分:0)
请勿在{{1}}上致电ToList()
。这将在内存中实现这些记录,这将导致整个allXNotDeleted
表也在内存中实现以执行连接。
试试这个:
XStatuses
这只会向SQL Server发送一个查询,并且只会实现查询返回的“notDeleted”值。不要忘记将using(var context = new DataContext(connectionString))
{
var allXNotDeleted =
from w in context.GetTable<CoolTable>()
where x.IsDeleted != false;
var allXWithCompleteStatus = (
from notDeleted in allXNotDeleted
join s in context.GetTable<XStatuses>()
on notDeleted.StatusID equals s.StatusID
where s.StatusID == 1
select notDeleted)
.ToList();
return allXwithCompleteStatus;
}
实例包含在using语句中,以便在{off {=}上下文时正确调用DataContext
。
另外,您的意思是使用Dispose()
过滤CoolTable
吗?这相当于IsDeleted != false
,这对我来说表示您要加入所有已删除的记录(变量名称IsDeleted == true
似乎相互矛盾)。
编辑:更新的代码以使用单个allXNotDeleted
实例,这应该消除“查询包含对另一个DataContext的引用”错误。如果您没有使用派生的DataContext
类,则需要将ConnectionString
传递给DataContext
构造函数。