1

我正在通过 linq to 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();

    }

这仍然会引发跨上下文查询异常

4

3 回答 3

3

无法直接在数据库上执行跨数据上下文查询。在内存中获取其中一个记录集 (ToList()) 会强制另一个加入的记录集在内存中进行处理。

如果要在 sql server 上执行所有操作,则必须将每个实体都放在同一个 DataContext 中。

于 2013-01-25T15:44:06.547 回答
0

我建议不要打电话ToList开始allXNotDeleted。这会将这些记录拉入内存,这可能意味着您在执行第二次查询时无法避免将所有其他数据拉入内存。

编辑:

作为附加说明,如果您的表特别大,并且您只需要来自几列的数据,您可以在数据库对象模型中为不需要的列设置Delay Loaded为。True

编辑2:

我刚刚注意到这两个查询都来自不同的上下文。在这种情况下,我建议您创建一个存储过程并从其中一个上下文中调用它。存储过程应该负责跨越上下文。

于 2013-01-25T15:40:52.713 回答
0

不要打电话ToList()allXNotDeleted这会在内存中具体化这些记录,这将导致整个XStatuses表也在内存中具体化以执行连接。

试试这个:

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;
}

这只会向 SQL Server 发送一个查询,并且只会具体化从查询返回的“notDeleted”值。不要忘记将您的DataContext实例包装在 using 语句中,以便Dispose()在它们脱离上下文时正确调用。

另外,你的意思是过滤CoolTableIsDeleted != false?这相当于IsDeleted == true,对我来说,这表明您要加入所有已删除的记录(变量的名称allXNotDeleted似乎与此相矛盾)。

编辑:更新代码以使用单个DataContext实例,这应该消除“查询包含对另一个 DataContext 的引用”错误。如果您不使用派生类,则需要将 传递ConnectionString给构造函数。DataContextDataContext

于 2013-01-25T15:45:30.603 回答