【问题标题】:Entity Framework Query: What's Happening Under the Covers Here?实体框架查询:幕后发生了什么?
【发布时间】:2023-03-14 17:33:02
【问题描述】:

我有以下代码。

var category = Office.Categories.FirstOrDefault(c => c.Description == name);

Office 是之前读取的框架实体对象。

即使我的数据库使用不区分大小写的字符串比较,并且其中一项完全匹配,除了大小写之外,此代码仍返回 null

我对这里发生的事情的理解是 Office.Categories 正在返回所有相关的行,然后这些行正在由区分大小写的常规 LINQ 搜索。

如果是这样,那效率太低了,因为我只想返回符合我的条件的行。

谁能证实我对此的理解?是否可以强制在 SQL 中进行过滤,这样我就不需要返回我不感兴趣的行? (而且文本比较会不区分大小写?)

感谢您的帮助。

【问题讨论】:

  • 我们不可能仅从您发布的代码中知道是在 SQL 中还是在内存中进行评估。
  • 好吧,我相信我已经确定它没有在 SQL 中进行评估。如果有问题,我可以提供更多信息。但我真的想在这里找出规则来确定它是否在 SQL 中进行评估,以及是否有办法覆盖它。

标签: c# .net linq entity-framework


【解决方案1】:

如果您已经加载了 Office 对象(也取决于延迟加载,但假设您在上下文之外),那么您基本上是在执行区分大小写的 linq-to-object 查询。如果你想做 linq-to-sql 那么你应该做不同的事情,比如:

context.Offices.FirstOrDefault(o=>o.OfficeId == someId)
                  .Categories.FirstOrDefault(c => c.Description == name);

context.Categories.FirstOrDefault(c => c.OfficeId == Office.OfficeId 
                                    && c.Description == name);

【讨论】:

  • 我必须用完,但稍后会尝试这些建议。
【解决方案2】:

正确,所以你不能:

  • 如果使用延迟加载,则调用 Categories 属性 getter,因为这会导致 EF 从数据库中检索完整的类别列表

  • 使用预先加载,因为这也会导致从数据库加载完整的类别列表

为避免这种情况,您可以使用以下代码(来自此答案:Using CreateSourceQuery in CTP4 Code First

    public ObjectQuery<T> CreateNavigationSourceQuery<T>(object entity, string navigationProperty)
    {
        var ose = this.ObjectContext.ObjectStateManager.GetObjectStateEntry(entity);
        var rm = this.ObjectContext.ObjectStateManager.GetRelationshipManager(entity);

        var entityType = (EntityType)ose.EntitySet.ElementType;
        var navigation = entityType.NavigationProperties[navigationProperty];

        var relatedEnd = rm.GetRelatedEnd(navigation.RelationshipType.FullName, navigation.ToEndMember.Name);

        return ((dynamic)relatedEnd).CreateSourceQuery();
    }

将它添加到您的上下文中并调用它来创建一个 ObjectQuery。您可以在此调用 FirstOrDefault,它不会从数据库中检索所有实体:

var category = context.CreateNavigationSourceQuery<Category>(Office, "Categories").FirstOrDefault(c => c.Description == name);

【讨论】:

  • 我在阅读这篇文章时遇到了一些麻烦。有一些错别字吗?您的意思是我可以执行以下任一操作吗?
猜你喜欢
  • 1970-01-01
  • 2012-10-26
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-09
  • 2011-07-12
  • 1970-01-01
相关资源
最近更新 更多