Group join 导致 IQueryable 变成 IEnumerable,为什么?

发布于 2024-12-10 21:25:59 字数 1366 浏览 0 评论 0原文

我正在访问远程数据源,发现组联接导致 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(_bility, x => x.eProfile.ID, y => y.ID, (x, y) => 新的 QuoteDTO

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

var cLists = List(); //这个集合是从客户端代码填充的,可以这么说 //为了参数而包含1,3,55...

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

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

I am accessing a remote data source and found that a group join causes an IQueryable query to be transformed into an IEnumerable,

question: will this affect performance? I want to offload as much of the query to the database as possible, and not execute anything in memory...

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
    })

    });

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

  1. _abilities is an IQueryable, I get the ability of a user, a collection of objects
  2. the second part (x,y) - here y gets transformed into an IEnumerable...

var cLists = List<int>(); //this collection is populated from the client code, lets say it
//contains 1,3,55 for arguments sake...

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

NOTE: the reason I use var is so that I can transform into an object of my liking, I was using a lot of anonymous types before the DTO objects were inserted...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

呆橘 2024-12-17 21:25:59

IQueryable 的定义:

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

...和 ​​ObjectQuery:

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 查询中。抱歉,我之前错过了这一点。

The definition of IQueryable:

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

...and ObjectQuery:

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

Most (all?) LINQ expressions return an object cast as IEnumerable. But the type of the object remains the type it started as.

No, the database is not hit when a LINQ-to-Entities query is cast as IEnumerable, so performance is not compromised. You can, if you'd like, upcast to either IQueryable or ObjectQuery.

Edit: For clarification, calling ToArray() on an instance of ObjectQuery, IQueryable, or IEnumerable does hit the database and retrieves a result set.

Edit: Creating a new object within a query (i.e. new QuoteDTO) will hit the database, because there's no way to store the new object in a SQL query. Sorry, I missed that bit before.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文