简体   繁体   中英

linq/ef: How to form the query which connects multiple tables to return result?

I'm extremely new to ASP .NET and LINQ so please forgive me for my ignorance.

I've a Region class:

public class Region
    {
        [Key]
        public int Region_ID { get; set; }
        public string Region_Name { get; set; }

    }

And a Service class:

public class Service
    {
        [Key]
        public int Service_ID { get; set; }
        public string Service_Name { get; set; }
    }

And a mapping class which stores the many-many mapping of service_IDs with region_IDs:

public class Mapping_ServiceToRegion
    {
        [Key]
        public int Service_ID { get; set; }
        public int Region_ID { get; set; }
    }

Now I want to create an API function which outputs Region_Name based on given Service_ID. This is what I have so far in my RegionsController:

// GET api/Regions/Service_ID
    [ResponseType(typeof(Region))]
    public async Task<IHttpActionResult> GetRegion(int id)
    {

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

        var region = await db.Regions.Select(r =>
            new Region()
            {
                Region_ID = r.Region_ID,
                Region_Name = r.Region_Name
            }).SingleOrDefaultAsync(r => r.Region_ID == region_id); //ERROR

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

        return Ok(region);
    }

The error I'm getting is:

Cannot convert lambda expression because it is not a delegate type.

I realize that my region_id variable will have multiple region_ids based on a service_id. How can I modify the code to account for this? Is there an IN operator that I can use to say r.Region_ID IN region_id?

And does the above code look correct otherwise?

Thanks.

You should change the SingleOrDefaultAsync() call using Contains() method like below since your region_id is of IEnumerable<T> and not a single value and so you can't perform direct equality comparison.

SingleOrDefaultAsync(r => region_id.Contains(r.Region_ID))

Ahh!!! here Region is one of EF mapped entity and you are trying to construct that and thus the error. You should either chose to select an Anonymous type (or) use a custom viewmodel/DTO object like

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

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