8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

使用 LINQ to SQL 和 Include() 进行预先加载

bakunet 2月前

94 0

我花了两天时间绞尽脑汁解决这个问题,但似乎无法解决它(问题本身)。在我添加数据库关系之前,相同的代码运行良好,从那时起我就......

我花了两天时间绞尽脑汁解决这个问题,但似乎无法解决它(问题本身)。在我添加数据库关系之前,相同的代码运行良好,从那时起,我阅读了很多 有关 延迟加载的资料。

我有两个数据库表,它们之间有 1:1 的关系。 PromoCode 表跟踪代码,并且有一个名为 PK 列的 id . CustomerPromo 链接到 PromoId 表的 PromoCode id 。这两个表没有其他关系。我在 SQL Server Management Studio 中生成了所有这些,然后从数据库生成了模型。

为了让事情稍微复杂一点,我在 WCF 数据服务中执行此操作,但我认为这不会有什么不同(在添加数据库关系之前它可以工作)。启用日志记录后,我总是在日志文件中收到带有文本的异常:

Dispose 之后访问 DataContext。

我的函数当前返回表中的所有条目:

using (MsSqlDataContext db = new MsSqlDataContext())
{
    // This causes issues with lazy-loading
    return db.PromoCodes.ToArray();
}

我读过无数文章/页面/答案,他们都说要使用这个 .Include() 方法。但这对我来说不起作用:

return db.PromoCodes.Include(x => x.CustomerPromos).ToArray();

我也尝试过“魔术字符串”版本:

return db.PromoCodes.Include("CustomerPromos").ToArray();

我设法使之起作用的唯一代码是:

PromoCode[] toReturn = db.PromoCodes.ToArray();

foreach (var p in toReturn)
    p.CustomerPromos.Load();

return toReturn;

我尝试过 .Where() 在查询中添加条件,尝试过 .Select() ,尝试过将移到 .Include() 后面 .Where() ( 这个答案 说最后这样做,但我认为这只是由于嵌套查询)。我读过关于 .Include() 将默默失败的 ,但经历了这一切,我还是没有更进一步。

我遗漏了什么?语法问题?逻辑问题?一旦我让这个 \'simple\' 案例工作起来,我还需要嵌套的 Include s (即,如果 CustomerPromo table 与 有关系 Customer )。

编辑
包括 所有 相关代码。其余的是 LINQ to SQL 或 WCF 数据服务配置。这就是全部内容:

[WebGet]
[OperationContract]
public PromoCode[] Test()
{
    using (MsSqlDataContext db = new MsSqlDataContext())
    {
        return db.PromoCodes.Include(x => x.CustomerPromos).ToArray();
    }
}

如果我直接通过浏览器调用该函数(例如 http://<address>:<port>/DataService.svc/Test ),我会收到重置连接消息,并且必须查找 WCF 日志才能找到 \' DataContext accessed after Dispose. \'。如果我通过网页中的 AJAX 调用进行相同的查询,我会收到带有状态的 AJAX 错误 error (仅此而已!)。

帖子版权声明 1、本帖标题:使用 LINQ to SQL 和 Include() 进行预先加载
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由bakunet在本站《linq》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 您能分享一下引发实际异常的代码片段吗?根据您上面的内容,这种情况会在您返回以下列表后发生:

  • 如果是这种情况,那是因为它在 WCF 数据服务中。它正在转换为 JSON。有一个

  • 到目前为止,您分享的唯一想到的事情是您正在尝试在 Using 块之外使用数据上下文。

  • 仅从阅读您的错误来看,我建议您不要返回使用(MsSqlDataContext db)的内部,而是创建一个数组变量,分配给它并调用 ToArray(),离开使用上下文,然后返回。这有什么改变吗?

  • 当我实际上没有任何子数据可获取时,我过早地发布了之前的答案。当时我只对获取父数据感兴趣,并且 那个答案 有效。

    现在,当我实际上也需要子数据时,我发现它不能完全工作。我发现 这篇文章 表明 .Include() (他说 Including() 但我不确定这是否是打字错误)已被删除,正确的解决方案是使用 DataLoadOptions 。此外,我还需要 启用单向序列化 .

    更糟糕的是,我不再需要 DeferredLoadingEnabled 。所以现在最终的代码如下所示:

    using (MsSqlDataContext db = new MsSqlDataContext())
    {
        DataLoadOptions options = new DataLoadOptions();
        options.LoadWith<PromoCode>(p => p.CustomerPromos);
        db.LoadOptions = options;
    
        return db.PromoCodes.ToArray();
    }
    

    设置后, Unidirectional Serialisation 它将愉快地返回父对象,而无需加载子对象,或明确设置 DeferredLoadingEnabled = false; .

  • 编辑: 这并没有完全解决问题。在测试时没有任何子数据,我也没有尝试使用它。这只允许我返回对象,它不返回子对象。有关完整解决方案,请参阅 此答案 .

    与我读过的所有内容相反,答案不是使用 .Include() 而是改变上下文选项。

    using (MsSqlDataContext db = new MsSqlDataContext())
    {
        db.DeferredLoadingEnabled = false; // THIS makes all the difference
        return db.PromoCodes.ToArray();
    }
    

    此链接 (感谢@Virgil)暗示了答案。但是我找不到访问 LazyLoadingEnabled LINQ to SQL 的方法(我怀疑它是针对 EntityFramework 的)。 此页面 指出 LINQ to SQL 的解决方案是 DeferredLoadingEnabled .

    的 MSDN 文档链接 DeferredLoadingEnabled .

返回
作者最近主题: