How to use async and await in LINQ?

天大地大妈咪最大 提交于 2020-01-14 10:29:08

问题


I'm new to ASP.NET and was trying to work on a sample project. I know this is a silly qs but please bear with me. My code below is returning only one result even when there are multiple rows returned in the SQL query. I realize that FirstOrDefaultAsync returns only the first element. I was going through the documentation here: https://msdn.microsoft.com/en-us/library/system.data.entity.queryableextensions(v=vs.113).aspx but I couldn't find what to use instead of FirstOrDefaultAsync that would return not just the first row but everything that matches my SQL condition.

This is my code so far:

    [ResponseType(typeof(Region))]
    public async Task<IHttpActionResult> GetRegion(int id)
    {

        var region_id = from sr in db.ServiceToRegions
                           where sr.Service_ID == id
                           select sr.Region_ID;

        var region = await db.Regions.Select(r =>
            new 
            {
                Region_ID = r.Region_ID,
                Region_Name = r.Region_Name
            }).FirstOrDefaultAsync(r => region_id.Contains(r.Region_ID)); //QQQ

        if (region == null)
        {
            return NotFound();
        }

        return Ok(region);
    }

What should I be using instead of FirstOrDefaultAsync?


回答1:


You should use ToListAsync() after Where:

var region = await db.Regions
    .Select(r =>
        new Region
        {
            Region_ID = r.Region_ID,
            Region_Name = r.Region_Name
        }
    )
    .Where(r => region_id.Contains(r.Region_ID))
    .ToListAsync();

https://msdn.microsoft.com/en-us/library/dn220257(v=vs.113).aspx

Note "new Region" to solve your anonymous type problem for serialization (I cannot comment on Scott's answer).

UDPATE

Because you try to partially load a model (only 2 properties), you need to use a ViewModel like this:

public class RegionVM
{
    public int Region_ID { get; set; }
    public string Region_Name { get; set; }
}

Then change your code for this:

var region = await db.Regions
    .Select(r =>
        new RegionVM
        {
            Region_ID = r.Region_ID,
            Region_Name = r.Region_Name
        }
    )
    .Where(r => region_id.Contains(r.Region_ID))
    .ToListAsync();

Don't forget to update your response type!




回答2:


You could replace the FirstOrDefaultAsync with a combination of a Where and a ToListAsync()

var region = await db.Regions.Select(r =>
        new 
        {
            Region_ID = r.Region_ID,
            Region_Name = r.Region_Name
        }).Where(r => region_id.Contains(r.Region_ID)).ToListAsync();

This will return a List<someAnnonamousType>.




回答3:


In that case you want all records, you should remove the call to FirstOrDefaultAsync() which will return you IEnumerable<anonymoustype> like below. You can include the condition using Where() LINQ extension method

    var region = await db.Regions                      
                  .Select(r =>
                      new 
                       {
                         Region_ID = r.Region_ID,
                         Region_Name = r.Region_Name
                       }).Where(r => region_id.Contains(r.Region_ID));


来源:https://stackoverflow.com/questions/38287545/how-to-use-async-and-await-in-linq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!