【问题标题】:Group join causes IQueryable to turn into IEnumerable, why?组加入导致 IQueryable 变成 IEnumerable,为什么?
【发布时间】:2011-10-20 15:25:01
【问题描述】:

我正在访问远程数据源,发现组连接导致 IQueryable 查询转换为 IEnumerable,

问题:这会影响性能吗?我想将尽可能多的查询卸载到数据库中,而不是在内存中执行任何内容...

var allusers = repo.All<User>().Where(x => x.IsActive);
var _eprofile = repo.All<Profile>()
    .Where(x => x.IsProfileActive)
    .Join(allusers, x => x.UserID, y => y.UserID, (x, y) => new
    {
        eProfile = x,
        profile = y
    })
    .GroupJoin(_abilities, x => x.eProfile.ID, y => y.ID, (x, y) => new QuoteDTO
    {
        UserID = x.profile.Login,
        Email = x.profile.Email,
        Tel = x.profile.Tel,
        Mobile = x.eProfile.Mobile,
        CompanyID = x.profile.CompanyID,
        Ability = y.Select(c => new AbilityDTO
    {
        Name= c.Name
    })

    });

行: .GroupJoin(_abilities, x => x.eProfile.ID, y => y.ID, (x, y) => new QuoteDTO

  1. _abilities是一个IQueryable,我得到一个用户的能力,一个对象的集合
  2. 第二部分 (x,y) - 这里 y 被转换为 IEnumerable...

var cLists = List&lt;int&gt;(); //这个集合是由客户端代码填充的,可以这么说 //出于参数考虑,包含 1,3,55...

 var _abilities= repo.All<UserAbility>()
      .Where(x => x.Status == Status.Active.ToString())
      .Where(x => cLists.Contains(x.CompetencyID));

注意:我使用 var 的原因是为了可以转换成我喜欢的对象,在插入 DTO 对象之前我使用了很多匿名类型...

【问题讨论】:

  • 哪个位被“转换为 IEnumerable”?什么是_abilities?
  • 它是一个子查询,我已经更新了上面的代码...
  • _abilitiesIQueryable 吗?所有变量的数据类型是什么?请不要使用var,我们无法推断变量类型以及编译器。
  • 上面的子查询我也要加...

标签: c# linq-to-sql iqueryable


【解决方案1】:

IQueryable的定义:

public interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable

...和对象查询:

ObjectQuery<T> : ObjectQuery, IOrderedQueryable<T>, IQueryable<T>, IEnumerable<T>, IOrderedQueryable, IQueryable, IEnumerable, IListSource

大多数(全部?)LINQ 表达式都返回一个转换为 IEnumerable 的对象。但是对象的类型仍然是它开始时的类型。

不,当 LINQ-to-Entities 查询被强制转换为 IEnumerable 时,不会命中数据库,因此不会影响性能。如果愿意,您可以向上转换为 IQueryable 或 ObjectQuery。

编辑:为澄清起见,对 ObjectQuery、IQueryable 或 IEnumerable 的实例调用 ToArray() 确实会命中数据库并检索结果集。

编辑:在查询中创建新对象(即新的 QuoteDTO)将访问数据库,因为无法将新对象存储在 SQL 查询中。抱歉,我之前错过了这一点。

【讨论】:

  • 看起来我的代码确实为它的子查询命中了数据库,这是我的实际问题,我想问上面的问题也可以帮助我解决这个问题
  • 你是对的。我编辑了我的答案。在查询中创建“新”对象将访问数据库并返回结果集。
  • 所以我应该为每个查询创建一个匿名对象,这样我就不会访问数据库了?
猜你喜欢
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多