Combining 2 select statement and join sql - c#

I'm currently having a problem on sql statement
here's my code
SELECT [Cities].ProvinceId,[Cities].Name,[Provinces].Name
FROM [Cities] JOIN Provinces
ON [Cities].ProvinceId = [Provinces].id
UNION
SELECT [Regions].RegionName,[Countries].CountryName
FROM [Regions] JOIN Countries
ON [Regions].RegionId = [Countries].RegionId
so basically what I am trying to do is that get the cities,province,region and countries.
I have 4 regions by the way which is
ASEAN = 1,ASIA = 2,WORLDWIDE = 3,DOMESTIC = 4
so DOMESTIC needs to be on the cities and province only because they are places local here in my country
and regions 1,2,3 are for countries but I could join theme because of these error
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
by the way I Applied it like this on my API
var provinces = await _provinceRepository.GetAll();
var cities = await _cityRepository.GetAllCities();
var result = provinces.Join(cities, p => p.Id, c => c.ProvinceId, (p, c) =>
new DestinationModel
{
Region = null,
City = c.Name,
State = p.Name,
Continent = null,
Country = null
}).ToList();
return Ok(result);
Now you can see my problem is that for now I can only get provinces and cities
the region and country are still null. Could someone help me with my query.

so basically what I am trying to do is that get the cities,province,region and countries.
Does this do what you want?
SELECT c.Name as city, p.Name as province, co.name as country,
r.name as region
FROM Cities c
JOIN Provinces p ON c.ProvinceId = p.id
JOIN Countries co ON p.CountryId = co.id
JOIN Regiones r ON co.RegionId = r.id;
To me, it seems like a more sensible result.

Related

LINQ multiple joins with a Group By not Working

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.

Adding Count Column to LINQ query Based on Joined Table

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:

LINQ Join gives only first result multiple times

I have this Join :
var mycust= db.CUSTOMER.Where(x => x.NAME.Contains(nameid)).ToList();
var CancCustomer = (from cust in myCust
join ip in db.IPS on must.ID equals ip.CUSTOMER_ID
select new JoinObj {ID = cust.ID, NAME = cust.NAME, LASTNAME = cust.LASTNAME,
TYPE_ID = ip.TYPE_ID, TYPE2_ID = ip.TYPE2_ID,
SERVICE_ID = ip.SERVICE_ID , REASON = ip.REASON }).ToList();
This code returns the first linq result multiple times? What am I missing? Thanks.
Instead of Where, you should use SingleOrDefault/Single - these would indeed return a single row into your mycust variable.
SingleOrDefault would put a null into the variable if no such customers were found (and assuming a Customer is a reference type - if it were a value type, it would be the default value for the type). Single would throw an exception if no items were found or more than one were found, which could be very useful in finding errors in your data (such as duplicate customer records).
Additionally, it is likely your ip table has multiple matching records for a customer - which is why you would be seeing multiple records being returned from your select.
You have multiple Duplicate Record received Then Try For following quires
var mycust= db.CUSTOMER.Where(x => x.NAME.Contains(nameid)).ToList();
var CancCustomer = (from cust in myCust
join ip in db.IPS on cust.ID equals ip.CUSTOMER_ID
select new JoinObj {ID = cust.ID, NAME = cust.NAME, ASTNAME=cust.LASTNAME, TYPE_ID = ip.TYPE_ID, TYPE2_ID = ip.TYPE2_ID, SERVICE_ID = ip.SERVICE_ID , REASON = ip.REASON }).distinct().ToList();
Other Wise Multiple record then You Get One Record for You following Query
var mycust= db.CUSTOMER.Where(x => x.NAME.Contains(nameid)).ToList();
var CancCustomer = (from cust in myCust
join ip in db.IPS on must.ID equals ip.CUSTOMER_ID
select new JoinObj {ID = cust.ID, NAME = cust.NAME, LASTNAME = cust.LASTNAME, TYPE_ID = ip.TYPE_ID, TYPE2_ID = ip.TYPE2_ID, SERVICE_ID = ip.SERVICE_ID , REASON = ip.REASON }).distinct().FirstOrDefault();

group by issue with extra columns

I group the result on the customers zipcode. For each zipcode, I want to see the amount of bookings and the amount of equipment that is ordered.
So far my code looks like this:
var statistics = from b in db.Bookings
from c in db.Customers
where b.customerID == c.id
group c by c.zipcode into stat
select new {
Zipcode = stat.Key,
NumberOfBookings = stat.Count()
};
This code groups result into zipcodes and gives me the amount of bookings in each zipcode. How to get the amount of equipment also?
Rather than using joins like in SQL, you can (and it's better) use the navigation properties from your model:
var statistics =
from b in db.Bookings
group b by b.Customer.zipcode into g
select new
{
Zipcode = g.Key,
NumberOfBookings = g.Count(),
NumberOfEquipments = g.SelectMany(b => b.Equipments).Count(),
};
Note that the g variable represents a set of bookings with the same zipcode, so SelectMany is used to get all associated equipments before applying the Count operator.
Of course that's not the only way, for instance you can use Sum instead:
NumberOfEquipments = g.Sum(b => b.Equipments.Count())

Linq with Lambda equivalent of SQL

I am relatively new to entity framework and I've been trying to write a Linq statement with Lambda that includes a simple join. I have three tables: Staff - StaffRole - Role.
I want a staff member in a certain role that satisfies a certain condition. Its very simple to write this in regular SQL:
SELECT *
FROM Staff s
INNER JOIN StaffRole sr ON s.StaffId = sr.StaffId
INNER JOIN Role r ON sr.RoleId = r.RoleId
WHERE r.Description = 'SpecialisedHealthManager'
AND s.PrimaryShm = 0
Now, writing it in a Linq statement has not given me much luck. I'm thinking it would be something like this:
var actingShm = db.Staff.Join(db.StaffRole,
inner => inner.StaffId,
outer => outer.Role,
(outer, inner) => new
{
StaffId = inner.StaffId,
FirstName = inner.Staff.FirstName,
Surname = inner.Staff.Surname,
SamAccountName = inner.Staff.SamAccountName,
RoleId = outer.Description
});
Needless to say, this is not working..
Try using it this way:
var list = from s in Staff
join sr in StaffRole on s.StaffId equals sr.StaffId
join r in Role on sr.RoleId equals r.RoleId
where r.Description == 'SpecialisedHealthManager' && s.PrimaryShm == 0
select new
{
StaffId = s.StaffId,
FirstName = s.Staff.FirstName,
Surname = s.Staff.Surname,
SamAccountName = s.Staff.SamAccountName,
RoleId = r.Description
});
Look here if you realy want to do this with method syntax LINQ:
SO Multiple tables join with lambdas
Also look here:
http://msdn.microsoft.com/pl-pl/library/bb534675(v=vs.110).aspx
for Join extension method syntax. Usage presented in your code is wrong.
You should have your associations setup so you can do this...
var actingShm = from s in db.Staff
from r in s.Roles
where r.Description == "SpecialisedHealthManager"
select new
{
StaffId = s.StaffId,
FirstName = s.FirstName,
Surname = s.Surname,
SamAccountName = s.SamAccountName,
RoleId = r.Description
});
Are you using Entity Framework or Linq2SQL?

Categories

Resources