简体   繁体   中英

How can I order in Linq Select Distinct if ordered by an Included entity?

I know that in Linq I have to do the OrderBy after doing a Select - Distinct , but I'm trying to order by an Included entity property that get lost after the Select .

For example:

var accounts = _context.AccountUser
                       .Include(o => o.Account)
                       .Where(o => o.UserId == userId || o.Account.OwnerId == userId)
                       .OrderByDescending(o => o.LastAccessed)
                       .Select(o => o.Account)
                       .Distinct();

As I'm doing the Where by an or of two different parameters, there is a good chance to obtain duplicated results. That's why I'm using the Distinct .

The problem here is that after I do the Select , I don't have the LastAccessed property anymore because it doesn't belong to the selected entity.

I thing the structure of the AccountUser and Account can be inferred from the query itself.

If you have the bi-directional navigation properties set up:

var accountsQuery = _context.AccountUser
  .Where(o => o.UserId == userId || o.Account.OwnerId == userId)
  .Select(o => o.Account)
  .Distinct()
  .OrderByDescending(a => a.AccountUser.LastAccessed);

When Selecting the Account you do not need .Include() Keep in mind that any related entities that you access off the Account will be lazy-loaded. I recommend using a .Select() to extract either a flattened view model or a view model hierarchy so that the SQL loads all needed fields rather than either eager-loading everything or tripping lazy-load calls.

Since LINQ doesn't implement DistinctBy and LINQ to SQL doesn't implement Distinct that takes an IEqualityComparer , you must substiture GroupBy + Select instead:

var accounts = _context.AccountUser
                       .Include(o => o.Account)
                       .Where(o => o.UserId == userId || o.Account.OwnerId == userId)
                       .GroupBy(o => o.Account).Select(og => og.First())
                       .OrderByDescending(o => o.LastAccessed)
                       .Select(o => o.Account);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM