I am new to C#, ASP.NET, MVC, LINQ and nearly everything else I'm doing. We've developed a working prototype of an event scheduling system that lists all events for all sites without regard to what site is scheduling what event. We are adapting the prototype to a full release and now want the schedulers to only see events for the sites they schedule.
My initial attempt is to populate a list of integers containing the ID of the sites the scheduler can schedule I would then use .contains to determine if the events are in the logged-in user's list of sites. So I have the following query which works (note that the user cannot yet select multiple sites which is why I am using .FirstOrDefault() because we have some data issues we're working with the customer to address. Also note that I've included the full method further below):
int site = (from u in context.Employees
join hf in context.SiteHomeFacs on u.Default_Location_Code equals hf.HomeFac
where u.User_ID == usr
select hf.siteID).FirstOrDefault();
var sites = new List<int> {site};
return sites;
Now I want to default some roles to being able to schedule all sites and this is where I start having problems (full method here):
public List<int> GetUserSites(string usr)
{
try
{
using (var context = new DBcontext())
{
if (HttpContext.Current.User.IsInRole("Owner") || HttpContext.Current.User.IsInRole("Controller"))
{
var everySite = (from s in context.Sites
select new List<int> { s.ID });
return everySite;
}
var site = (from u in context.Employees
join hf in context.SiteHomeFacs on u.Default_Location_Code equals hf.HomeFac
where u.User_ID == usr
select new List<int> { hf.siteID }).FirstOrDefault();
return sites;
}
}
catch (Exception)
{
throw;
}
}
The error at 'return everySite' is:
Cannot implicitly convert type 'System.Linq.IQueryable>' to 'System.Collections.Generic.List'. An explicit conversion exists (are you missing a cast?)
To me it seems counter-intuitive that the query would be acceptable with .FirstOrDefault()
, but not without it. Can someone help me to return a list of integer values so I can use .contains? Or suggest a better way over all?
In order to solve this issue , you can do this,
Add a ToList()
at the end to convert the IQueryable result returned to an IList,
var everySite = from s in context.Sites select s.ID ;
return everySite.ToList();
EDIT: In order to support large list you could return a HashSet as mentioned in the comment below ,
return new HashSet<int>(everySite);