I'm using MVC3 and still learning LINQ. I'm having some trouble trying to convert a query to LINQ to Entities. I want to return an Json method
My stored procedure
Create Procedure [dbo].[ResourceReports]
(
#EmployeeID int
)
as
begin
select p.projectName AS Projects, count( b.[CreatedByID]) AS Bugs
from [EmployeeDetails] e inner join [Bugs] b on e.[EmployeId] = b.[CreatedByID]
inner join Projects p on b.ProjectId = p.ProjectId
where e.[EmployeId] = #EmployeeID
group by P.projectName
end
What I have is a few tables, I started writing this out in LINQ but I'm not sure how to properly return the correct type or cast this.
My controller
public JsonResult Getchart()
{
var Bug = db.Bugs.ToList<Bug>();
var EmployeDetails = db.EmployeeDetails.ToList<EmployeeDetail>();
var projects = db.Projects.ToList<Project>();
var result = (from e in EmployeDetails
join b in Bug on e.EmployeId equals b.CreatedByID
join p in projects on b.ProjectId equals p.ProjectId
where e.EmployeId = #EmployeId
group p.projectName
select new (p.projectName as Project ,count(b.CreatedByID) as Bug)).Take(50);
return Json(result,JsonRequestBehavior.AllowGet);
}
How will I pass the parameter to for the query, want the data to be returned in json format.
Assuming you can pass the value in as a parameter to the method:
public JsonResult Getchart(int employeeId)
{
var Bug = db.Bugs.ToList<Bug>();
var EmployeeDetails = db.EmployeeDetails.ToList<EmployeeDetail>();
var projects = db.Projects.ToList<Project>();
var result = (from e in EmployeeDetails
join b in Bug on e.EmployeeId equals b.CreatedByID
join p in projects on b.ProjectId equals p.ProjectId
where e.EmployeeId == employeeId // <-- use the parameter here
group p by p.projectName into g
select new {
Project = g.Key,
Bug = g.Count()
}
).Take(50);
return Json(result,JsonRequestBehavior.AllowGet);
}
BTW I intentionally corrected a few spellings of Employee
If this is a controller action, you would probably want to pass the ID via the URL. Also, there is no need to call ToList on your tables before querying, do the query at the database and only pull down the results e.g.
public JsonResult GetChart(int employeeId)
{
var query = (from e in db.EmployeeDetails
join b in db.Bugs on e.EmployeeId equals b.CreatedById
join p in db.Projects on b.ProjectId equals p.ProjectId
where e.EmployeeId == employeeId
group new {p, b} by new {
p.ProjectName
} into g
select new {
Project = g.Key.Name,
Bugs = g.Count()
}).Take(50);
return Json(query.ToList(), JsonRequestBehaviour.AllowGet);
}
Is this what you need:
public JsonResult Getchart(int employeId)
{
var Bug = db.Bugs.ToList<Bug>();
var EmployeDetails = db.EmployeeDetails.ToList<EmployeeDetail>();
var projects = db.Projects.ToList<Project>();
var result = (from e in EmployeDetails
join b in Bug on e.EmployeId equals b.CreatedByID
join p in projects on b.ProjectId equals p.ProjectId
where e.EmployeId == employeeId
group p.projectName
select new (p.projectName as Project ,count(b.CreatedByID) as Bug)).Take(50);
return Json(result,JsonRequestBehavior.AllowGet);
}
Are you sure you want to do all of those "ToList<>()" calls? Once you call "ToList<>()", you bring all three of those tables into memory from the database. If they are large, that could be a performance issue.
public JsonResult GetChart()
{
//int employeeId
var Bug = db.Bugs.ToList<Bug>();
var EmployeDetails = db.EmployeeDetails.ToList<EmployeeDetail>();
var projects = db.Projects.ToList<Project>();
var query = (from e in EmployeDetails
join b in Bug on e.EmployeId equals b.CreatedByID
join p in projects on b.ProjectId equals p.ProjectId
where e.EmployeId == 1
group new { p, b } by new
{
p.projectName
} into g
select new ChartModel
{
ProjectName = g.Key.projectName,
bug = g.Count()
}).ToList();
return Json(query, JsonRequestBehavior.AllowGet);
}
i Got ...
Related
After trying a lot i couldn't get this to work
I have below query:
var query = from citiez in db.cities
join site in db.sites on citiez.city_id equals site.city_id
join ords in db.orders on site.site_id equals ords.site_id
group site by site.site_id into grouped
select new {
sit = grouped.Count(),
cits = grouped.FirstOrDefault().orders
.Where(o => o.site.city.city_name == city)
};
var list = query.ToList();
It works fine but gives Circular reference error.
I have searched it but couldn't get this to work in my case
What i am trying to do in SQL is:
SELECT s.site_id, COUNT(o.order_id) TotalOrders
FROM city c
INNER JOIN site s ON c.city_id = s.city_id
INNER JOIN dbo.[order] o ON s.site_id = o.site_id
WHERE c.city_id = 4
GROUP BY s.site_id
The Query returns the desired result in SSMS.
EDIT
This is my Controller Action code:
public ActionResult draw_chart(string city)
{
var query = from citiez in db.cities
join site in db.sites on citiez.city_id equals site.city_id
join ords in db.orders on site.site_id equals ords.site_id
group site by site.site_id into grouped
select new
{
sit = grouped.Count(),
cits = grouped.FirstOrDefault().orders
.Where(o => o.site.city.city_name == city)
};
var list = query.ToList();
return Json(list, JsonRequestBehavior.AllowGet);
}
Any help would be much Appreciated.
Try this one your controller action. you will get site id and orders for site
public ActionResult draw_chart(string city)
{
var query = from citiez in db.cities
join site in db.sites on citiez.city_id equals site.city_id
join ords in db.orders on site.site_id equals ords.site_id
where citiez.city_name == city
group site by site.site_id into grouped
select new
{
siteId = grouped.Key,
ordersforsite = grouped.Count(),
};
var list = query.ToList();
return Json(list, JsonRequestBehavior.AllowGet);
}
That Linq doesn't look like the SQL you showed and most of the time you don't need to use JOIN (provided you have a good database design with relations setup). Based on your SQL you can use a Link query like this:
var result = db.Orders
.Where(o => o.City_id == 4)
.GroupBy(o => o.Site.Site_id)
.Select(g => new {
Site_id = g.Key,
TotalOrders = g.Count
});
What you intend can be expressed in this query:
var query = from citiez in db.cities
where citiez.city == city
from site in citiez.sites
select new {
sit = site.orders.count,
cits = site.orders
};
That would give you the orders for each site.
So I have a SQL view that I've created that provides me what I need. Essentially it's a job position billeting system that shows how many positions have been authorized vs filled (or assigned).
SELECT Companies.Name AS Company, Grades.Name AS Grade, Series.Name
AS Series, Positions.Authorized, COUNT(People.PersonId) AS Assigned
FROM Companies INNER JOIN
Positions ON Companies.Id = Positions.CompanyId INNER JOIN
Series ON Positions.SeriesId = Series.Id INNER JOIN
Grades ON Positions.GradeId = Grades.Id INNER JOIN
People ON Positions.CompanyId = People.CompanyId AND
Positions.SeriesId = People.SeriesId AND Positions.GradeId = People.GradeId
GROUP BY Companies.Name, Grades.Name, Series.Name, Positions.Authorized
Now what I'd like to be able to do is recreate this in a LINQ query. I've almost got it where I need it; however, I can't figure out how to add the counted column at the end that's based on the People table.
Here's my current LINQ query:
var query = from a in db.Companies
join b in db.Positions on a.Id equals b.CompanyId
join c in db.Series on b.SeriesId equals c.Id
join d in db.Grades on b.GradeId equals d.Id
join e in db.People on new { b.CompanyId, b.SeriesId, b.GradeId } equals new { e.CompanyId, e.SeriesId, e.GradeId }
group a by new { CompanyName = a.Name, GradeName = d.Name, SeriesName = c.Name, b.Authorized, e.PersonId } into f
select new { Company = f.Key.CompanyName, Grade = f.Key.GradeName, Series = f.Key.SeriesName, f.Key.Authorized, Assigned = /* needs to be Count(People.PersonId) based on last join */ )};
Thanks in advance for any help you can provide!
Figured it out. The reason why it was posting multiple rows and not doing a proper count on the same row was because in my "group by" I added in "e.PersonId" when it should have simply been removed. I also had to add a few things to make it work on the front-end razor views since it's an anonymous type (this doesn't have anything to do with the original question, but thought I'd give reason to the changes). So the person who removed their answer, you were partially right, but the reason it wasn't working was because of the additional fieldin the group by:
dynamic query = (from a in db.Companies
join b in db.Positions on a.Id equals b.CompanyId
join c in db.Series on b.SeriesId equals c.Id
join d in db.Grades on b.GradeId equals d.Id
join e in db.People on new { b.CompanyId, b.SeriesId, b.GradeId } equals new { e.CompanyId, e.SeriesId, e.GradeId }
group a by new { CompanyName = a.Name, GradeName = d.Name, SeriesName = c.Name, b.Authorized } into f
select new { Company = f.Key.CompanyName, Grade = f.Key.GradeName, Series = f.Key.SeriesName, Authorized = f.Key.Authorized, Assigned = f.Count()}).AsEnumerable().Select(r => r.ToExpando());
And what it looks like on the page:
I would like to use my entity class properties in my linq query that return some value with it.
so this my linq query;
List<PvmBarChartData> BaseofSegmentIPPGMR = (from si in db.ScoreItem
join s in db.Score on si.ScoreId equals s.Id
join prg in db.ProjectResearchGroup on si.ProjectResearchGroupId equals prg.Id
join rg in db.RgClone on prg.RgCloneId equals rg.Id
join sp in db.SalesPoint on s.SalesPointId equals sp.Id
join c in db.Channel on sp.ChannelId equals c.Id
where (si.ResearchGroupType == ResearchGroupType.ScoreCard && spIds.Contains(s.SalesPointId))
group si by c.Name into g
select new PvmBarChartData
{
GroupName = g.Key,
DataValues = new List<CvmNameValuePair>{ new CvmNameValuePair{
Name = "",
Value = g.Average(x => x.TotalScore)
}
}
})
.ToList();
so for instance I would like to set Name properties with my entity framework model class' properties' value, Name = s.Name,
How can I implement this on my code?
A way that you can access s.Name is by doing another linq query on g, since g is now a data set of grouped objects.
Name = (from gx in g select gx.Name).FirstorDefault();
I have this query below. After that, I want to populate a list with the results. How should I do ?
var query = from cust in context.Customer
join city in context.Cities on cust.id_city equals city.id
join state in context.State on city.id_state equals state.id
join reg in context.Region on state.id_region equals reg.id
select new
{
nameCust = cust.name,
nameCity = city.name,
nameState = state.name,
nameRegion = reg.name
};
You should be able to call ToList() on the return value:
var queryResult = (from cust in context.Customer
join city in context.Cities on cust.id_city equals city.id
join state in context.State on city.id_state equals state.id
join reg in context.Region on state.id_region equals reg.id
select new
{
nameCust = cust.name,
nameCity = city.name,
nameState = state.name,
nameRegion = reg.name
}).ToList();
I'm wondering though, if you are using Entity Framework. If so: this might be a bether solution:
var queryResult = context.Customer
.Include(customer => customer.City)
.Include(customer => customer.State)
.Include(customer => customer.Region)
.ToList();
( ! ) Keep in mind you are loading a complete table into memory using ToList()
I trying to write sql query to linq:
Query:
select s.s_name, sub.state, sub.to, sub.evaluation, sub.task_id
from submit_task sub
join student s on s.id=sub.student_id
join task t on t.id=sub.task_id
where t.t_name = "bbbb";
Linq:
var subTask = (from sub in ado.submit_task
join s in ado.student on sub.student_id equals s.id
join t in ado.task on sub.task_id equals t.id
where t.t_name == listView3.SelectedItems[0].Text
select new { s.s_name, sub.state, sub.to,
sub.evaluation, sub.task_id });
but this not working. When I try dubugg, nothing's happened, with no error or result. Do you see some mistake ??
thankk you
var text = listView3.SelectedItems[0].Text;
var subTask = (from sub in ado.submit_task
join s in ado.student on sub.student_id equals s.id
join t in ado.task on sub.task_id equals t.id
where t.t_name == text
select new { s.s_name, sub.state, sub.to, sub.evaluation, sub.task_id });