简体   繁体   中英

OrderBy clause breaks my controller in Entity Framework Core 3

So I had this little controller that is working great. The only issue, is that the StateLocation OrderId was out of order in the returned string.

[HttpGet("GetLocationsByLanguageId/{id}")]
public async Task<ActionResult<IEnumerable<LanguageList>>> GetLocationsByLanguageId(Guid id)
{
    var choicesByLanguage = await _context.LanguageList.Where(q => q.LanguageId == id)
                    .Include(p => p.StateLocation)
                    .ToListAsync();
    return choicesByLanguage;
}

So I went to the Microsoft Entity Framework site to read about ordering and found this:

https://learn.microsoft.com/en-us/ef/core/querying/related-data/eager

So I added an OrderBy clause like you see below:

[HttpGet("GetLocationsByLanguageId/{id}")]
public async Task<ActionResult<IEnumerable<LanguageList>>> GetLocationsByLanguageId(Guid id)
{
    var choicesByLanguage = await _context.LanguageList.Where(q => q.LanguageId == id)
                    .Include(p => p.StateLocation
                            .OrderBy(p => p.OrderId))
                            .ToListAsync();
    return choicesByLanguage;
}

I don't get any errors on build, but when I try to hit the site, I get this:

Expression of type 'System.Linq.IOrderedQueryable' cannot be used for return type 'System.Linq.IOrderedEnumerable

So I searched around for that found a few possible solutions here:

OrderBy and List vs. IOrderedEnumerable

But none of those worked, they just generated new errors or variations on of the original error.

I've had trouble finding any answers that help with this issue when using.Net Core 3. Most of the answers are for older versions.

Has anyone been able to solve this.Net Core Entity Framework 3.0?

Thanks!

Models:

public partial class LanguageList
{
    public LanguageList()
    {
        StateLocation = new HashSet<StateLocation>();
    }
    
    public Guid LanguageId{ get; set; }
    public string LanguageName { get; set; }

    public virtual ICollection<StateLocation> StateLocation { get; set; }
}

public partial class StateLocation
{
    public Guid StateId { get; set; }
    public Guid LanguageId { get; set; }
    public string StateName { get; set; }
    public string StateCapital { get; set; }
    public int OrderId { get; set; }

    public virtual LanguageList Language { get; set; }
}

Try this:

return  await _context.LanguageList
                    .Where(q => q.LanguageId == id)
                    .Include(p => p.StateLocation.OrderBy(p => p.OrderId))
                     .ToListAsync();

You almost made this query, but since you put the extra ")" in a wrong place it gave the error.

but if you still use EF Core 3 you can try this:

var query=  await _context.LanguageList
              .Where(q => q.LanguageId == id)
        .Select(p => new
        {
            P = p,
            C = p.StateLocation.OrderBy(p => p.OrderId))
        })
    .ToListAsync();

return  query
            .Select(g => g.P)
            .FirstOrDefault();

You mention you're using EF Core 3, however, the documentation states that this functionality was first introduced in EF Core 5.0. That is, you cannot perform LINQ operations on the related data in a single query. Instead you need to either upgrade to EF Core 5.0 or perform the ordering after your ToListAsync call.

Example in EF Core 3:

var choicesByLanguage = await _context.LanguageList.Where(q => q.LanguageId == id)
    .Include(p => p.StateLocation)
    .ToListAsync();

foreach (var lList in choicesByLanguage)
{
    lList.StateLocation = lList.StateLocation.OrderBy(p => p.OrderId).ToList();
}

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