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?
Note that there are no async versions of some LINQ operators such as Where or OrderBy, because these only build up the LINQ expression tree and don't cause the query to be executed in the database. Only operators which cause query execution have async counterparts.
Generally speaking, if there are asynchronous APIs, then you should use them for new code. Asynchronous code frees up the calling thread. If your application is a GUI application, this can free up the UI thread; if your application is a server application, this can free up threads to handle other requests.
The async keyword turns a method into an async method, which allows you to use the await keyword in its body. When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete. await can only be used inside an async method.
I/O multiplexing—select() Like asynchronous I/O, the select() API creates a common point to wait for multiple conditions at the same time. However, select() allows an application to specify sets of descriptors to see if the following conditions exist: There is data to be read. Data can be written.
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!
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>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With