【问题标题】:Linq to entities DbQuery object is failing hardLinq 到实体 DbQuery 对象严重失败
【发布时间】:2015-07-16 14:28:19
【问题描述】:

我想知道是否有人可以对这里可能发生的事情有所了解。我正在使用 C#、MVC 和实体框架。

所以我运行这两行代码:

var booboo = _context.AppItems.Where(ai => ai.id == 101);
var sql = booboo.ToString();

我得到了一些奇怪的行为。 booboo.ToString() 方法挂起,因此失败。事实上,booboo DbQuery 对象没有任何东西可以正常工作。 我的 AppItem 实体在整个代码中都遇到了类似的问题(您可能猜到,AppItems 是 DbSet)。实体框架似乎无法为 AppItem 实体构造查询。

编辑: 我不够耐心!离开它很长时间后,我确实得到了以下异常: “消息=内部错误:已达到表达式服务限制。请在查询中查找可能复杂的表达式,并尝试简化它们。” 有趣的是,这是我没想到的 Sql.Client 异常。

AppItem 类如下所示:

public class AppItem : Domain.Item
{
    public int? UserProfileId { get; set; }
    public virtual UserProfile UpdatedByUser { get; set; }

    [MaxLength(50)] 
    public String Type { get; set;}

    public DateTime UpdatedDate { get; set;}

    // flags
    public virtual ICollection<ItemFlag> Flags { get; set; }

    // actions
    public virtual ICollection<ItemAction> Actions { get; set; }

    // notes
    public virtual ICollection<Note> Notes { get; set; }
}

Domain Item 包含一个主键字段 (id) 和一些其他字段。

那里的 Note / ItemAction / ItemFlag 类都继承自 AppItem,所以也许是某种循环引用的原因?

其他项目可以查询就好了。例如,我有许多继承自 AppItem 的类(如 ItemFlag、ItemAction 和 Note),我可以很好地查询所有这些类。 所以,Members 是 DbSet,Member 继承自 AppItem:

var foofoo = _context.Members.Where(ai => ai.id = 101);
var sql = foofoo.ToString();

这很好用; foofoo.ToString() 返回构造好的 SQL,一切看起来都井井有条。

这对我来说真的很奇怪,没有错误消息或任何东西,应用程序在尝试查询 AppItems 时只是挂起。该表存在于数据库中,但这并不重要,因为我们没有达到查询数据库的程度,我们一开始就无法构造查询。

提前感谢您的帮助。

【问题讨论】:

    标签: c# linq entity-framework


    【解决方案1】:

    我发现了问题所在。 我正在使用 Table-per-Type 进行继承。由于 AppItem 是一个基本类型,它为查询它而生成的 SQL 查询非常庞大(在这种情况下长达数千行)并且会导致问题。 因此,基本上,在使用 Table-per-Type 时,您需要避免查询具有多个继承自它们的类型的基本类型。

    【讨论】:

      【解决方案2】:

      我假设您的查询旨在返回 1 项。

      在查询末尾添加 .FirstOrDefault(); 以仅返回一项(您当前的查询返回 AppItems 类型的 IQueriable)

      实体框架在需要之前不会执行查询,因此在您的代码中,它将在调用 .ToString() 方法时执行查询。

      试试这个:

      var booboo = _context.AppItems.Where(ai => ai.id == 101).FirstOrDefault();
      
      if (booboo != null)
      {
          var sql = booboo.ToString();
      
          //etc
      }
      

      【讨论】:

      • 是的,这些我都知道。如果我运行您发布的代码,应用程序会挂在第一行。不管我运行什么查询,如果我尝试在任何 DbQuery 对象上运行任何方法,无论该方法是 FirstOrDefault() 还是 ToString(),应用程序都会挂起。
      • 嗯..你试过在它周围放一个try-catch块吗?它似乎在默默地生病……
      • 数据库也在本地服务器上吗?还是托管在其他地方?
      • try-catch 没有帮助,因为它挂起,不会产生异常。所以它只是卡在 try 块内的同一行。数据库位于同一房间的单独服务器上。我从我的开发机器访问数据库并对其运行 sql 查询没有问题。我对 AppItem 表运行 sql 查询没有问题。数据库不可能是问题,因为它没有那么远。 DbQuery 对象甚至不能在不挂起的情况下生成 SQL 字符串。
      • 当我离开的时间足够长时出现异常。我编辑了原始问题并将消息放在那里。
      猜你喜欢
      • 1970-01-01
      • 2013-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      • 2017-03-08
      相关资源
      最近更新 更多