【问题标题】:Linq randomly returns periodic null resultsLinq 随机返回周期性空结果
【发布时间】:2025-11-23 02:10:01
【问题描述】:

我有一个 linq 查询,这无疑是相当大的。我无法确定哪里出了问题,因为它只发生在远程服务器上,我无权调试它。不过基本是这样的……

此代码列出了当前成员可以看到的所有“文件夹”。 (文件夹包含图像。)

            if (membership == null || membership.Count() == 0)
                membership = new string[] { "Guests" };

            return DataContext.Folders.Where(f => f.Ring.Keys.Any(k => k.Tag.Id == id))
                .Where(i => i.Ring.Keys.Any(t => membership.Contains(t.Tag.Name))).OrderBy(n => n.Date).DefaultIfEmpty();

此代码列出了用户可以看到的所有“标签”(标签包含在环中,可以挂在文件夹或图像上)

        IQueryable<Models.Tag> tags = null;
        do
        {
            DataContext = new Models.Contexts.DatabaseDataContext();

            tags = null;
            if (membership == null)
                membership = new string[] { "Guests" };

            tags = DataContext.Tags.Where(t => t.Keys.Any(k => k.Ring.Name == category))
                .Where(t => t.Keys.Any(k => k.Ring.Keys.Any(c => membership.Contains(c.Tag.Name)))).OrderBy(o => o.Name);
        }
        while (tags == null || tags.Count() == 0);

        return tags;

我将它封闭在一个 do 循环中,这让我很沮丧,看看它是否可以强制它实际继续调用,直到它不再为空。没有这样的运气,它仍然空无一物。同样,这个完全相同的代码“有时”工作,并且在每次测试中 100% 的时间都在查询相同的数据库。我什至尝试过不同的网络主机——一旦上线,都会出现同样的故障。

membership 是一个字符串[],其中包含该成员所属的所有角色的列表。

Folder
- Id
- RingId

Ring
- Id
- Name (Nullable)

Tag
- Id
- Name

Key
- Id
- RingId
- TagId

Image
- Id
- FolderId
- RingId

这是基本的数据库结构设置。

现在,这个查询在我的本地机器上运行良好 - 在我的所有测试等中。但是当我把它上线时,它只是随机开始返回 null 有时。我找不到押韵或原因,它对一些请求运行良好,然后它就停止返回结果。

它返回的结果集非常大。我会说大约880个项目。每秒访问它的次数非常非常高。起初我想也许这只是有多少人访问它的压力。

我可以提供任何有助于调试的信息吗?还有一些与此类似的其他查询-我已经尝试过,尝试过,尝试过,但我根本无法在调试器中重现结果。我收到了各种各样的 InvalidCastException 调用——但从来没有任何强制转换。一切都以 IQueryable 的形式返回——除了接受 Guid 并从 ASP.NET Membership Provider 传递 Membership 数据外,视图没有做任何特别的事情——我已经检查并确认它正在工作。 (插入强制数据,而不是让提供者这样做 - 仍然失败)

我会尽力提供任何需要的信息,但我真的很沮丧——因为这对我来说毫无意义(为什么会失败)。

非常感谢您的宝贵时间。 (这一切都在 .NET 3.5、ASP.NET MVC 1.0、C# 中完成)- 对象是使用 LINQ to SQL 创建的。

【问题讨论】:

  • 数据上下文是一次性的,你有什么理由不通过在 using 语句中包装它的生命周期来处理它?
  • 我不熟悉这种做法。你建议以这种方式包装它吗?我自称是初学者。
  • 将它包含在 using 语句中只会给我一个 System.ObjectDisposedException。返回在 using 语句中 - 如果我要处理数据上下文,我不确定如何从中获取数据。

标签: c# asp.net-mvc linq .net-3.5


【解决方案1】:

这听起来确实是一个负载问题。在网络服务器上放置一些性能计数器并观察它的使用情况。

【讨论】:

  • 如果是负载问题,您建议如何解决?我不是在廉价或薄弱的网络服务器上运行它。它可以很好地运行其他大型应用程序。但负载在每小时 10,000 到 25,000 次点击之间。
  • 如果它是基于负载的,那么您唯一的解决方案就是横向扩展应用程序,以便您有足够的 Web 服务器来处理负载而不会达到魔法边界。除此之外,创建一个示例应用程序并直接联系 MS 支持,看看他们是否可以修复错误。
【解决方案2】:

好的,我不确定这是否是您的问题,但在评论中写回它太难了,

假设您使用的是 LINQ to SQL,您的数据上下文是一次性的。因此,当您想使用它时,您可以将其包装在 using 语句中,如下所示:

    do
    {
        using (DataContext = new Models.Contexts.DatabaseDataContext())
        {

            tags = null;
            if (membership == null)
                membership = new string[] { "Guests" };

            tags = DataContext.Tags.Where(t => t.Keys.Any(k => k.Ring.Name == category))
                .Where(t => t.Keys.Any(k => k.Ring.Keys.Any(c => membership.Contains(c.Tag.Name)))).OrderBy(o => o.Name);
        }
    }

这样,它会在每次尝试使用它后释放您的连接,否则它将在内存中保留一段时间。因为这段时间取决于垃圾收集器,所以这可能是它有时工作而不是其他时间的原因。试试看,如果它解决了您的问题,请告诉我。

【讨论】:

  • 这不起作用,因为数据上下文在视图尝试呈现从它获取的数据时被释放。
  • 我也试过关闭延迟加载,但我遇到了同样的问题。有什么方法可以访问 DataContext 被处理后检索到的数据?
  • 与大多数实现 IDisposable 的类型不同,DataContext 并不真正需要处理 - 至少在大多数情况下不需要。见csharpindepth.com/ViewNote.aspx?NoteID=89
  • :(不幸的是,我的问题还是回到了原点。
  • 这在某种程度上很有帮助,因为它让我能够更多地了解 Linq 并评估不同的做事方式 - 但它并不能解决问题 - 另外处理也没有帮助,因为我仍然需要视图中的数据。