Correct sql to linq query - c#

I'm having difficulty converting this sql query to a linq query. I'm trying to select all my orders with the order details attached to that order. In sql the query is correct. When I write it in linq is when everything goes haywire. Here is my code:
var result = from order in orders
join orderDetail in orderDetails
on order.OrderID equals orderDetail.OrderID
select new OrderVm
{
OrderId = order.OrderID,
OrderDetails = order.Order_Details.Select(x =>
new OrderDetailVm
{
OrderId = orderDetail.OrderID,
UnitPrice = orderDetail.UnitPrice,
Quantity = orderDetail.Quantity,
ProductId = orderDetail.ProductID
})
};
return result.ToList();
that produces this result
but in sql if I write
select
o.OrderID,
o.CustomerID,
od.UnitPrice,
od.Quantity,
od.productid,
p.ProductName
from Orders o
inner join [Order Details] od
on o.OrderID = od.OrderID
inner join Products p
on p.ProductID = od.ProductID
where o.OrderID = 10248
my expected out come is

It looks like from the way that you are using Order_Details in the nested object that the join already exists and that the join you are using is redundant.
var result = from order in orders
select new OrderVm
{
OrderId = order.OrderID,
OrderDetails = order.Order_Details.Select(x =>
new OrderDetailVm
{
OrderId = x.OrderID,
UnitPrice = x.UnitPrice,
Quantity = x.Quantity,
ProductId = x.ProductID
})
};

Related

Dapper selecting nested objects

My SQL looks like
Select TOP 3 o.OrderId,
o.Total,
od.Quantity,
od.ItemDescription,
os.OrderStatusDescription,
os.OrderStatusID
From dbo.Orders o
INNER JOIN dbo.OrderStatuses os ON os.OrderStatusID = o.OrderStatusID
INNER JOIN dbo.OrderDetails od ON od.OrderID = o.OrderID
Where o.CustomerId = 100 order by OrderDate desc;
I have my class on c# side as below, i have three tables on db side as well.
i am trying to see if i can use dapper to map 3 tables into one object Order withouty having to do multiple select querys.
i need top 3 rows from Order Table and its child tables loaded. OrderDetail can have n rows for 1 orderId.
How can i selected nested object with 1 look up using dapper?
class Order{
int OrderId {get;set;}
decimal Total {get;set;}
List<OrderDetail> Details {get;set;}
OrderStatus Status {get;set;}
}
class OrderDetail
{
int OrderLineId {get;set;}
int OrderId {get;set;}
string ItemDescription {get;set;}
int Quantity {get;set;}
}
class OrderStatus
{
int OrderStatusID {get;set;}
string OrderStatusDescription {get;set;}
}
this is what i have tried so far but not successful
sqlConnection.Open();
IEnumerable orders = sqlConnection
.Query<Order>(
#"select Order.*, OrderDetail.*
from Order join OrderDetail
inner join on Order.OrderId = OrderDetail.OrderId
inner join on Order.OrderStatusID = OrderStatus.OrderId
and Order.CustomerId = 100",
(o, od, os) =>
{
o.Details = od; //this is a List<OrderDetail>
o.Status = os;
return o;
}); //
There are some ways to achieve your case, but for me you can do this by the below code
var sql = #"Select TOP 3 o.OrderId,
o.Total,
os.OrderStatusID,
os.OrderStatusDescription,
od.OrderLineId,
od.Quantity,
od.ItemDescription
From dbo.Orders o
INNER JOIN dbo.OrderStatuses os ON os.OrderStatusID = o.OrderStatusID
INNER JOIN dbo.OrderDetails od ON od.OrderID = o.OrderID
Where o.CustomerId = 100 order by OrderDate desc;";
sqlConnection.Open();
var lookupOrders = new Dictionary<int,Order>();
var oders = sqlConnection.Query<Order, OrderStatus, OrderDetails, Order>(sql,
(o, os, od) =>
{
Order order;
if(!lookupOrders.ContainsKey(o.OrderId)){
lookupOrders.Add(o.OrderId, o);
order = o;
order.Details = new List<OrderDetail>();
}
else {
order = lookupOrders[o.OrderId];
}
order.Details.Add(od);
order.Status = os;
return order;
}, splitOn: "OrderId, OrderStatusID, OrderLineId"
).Distinct();

Linq query is getting more records than sql query

I have a sql query which will give me around 30 record but the same query once I changed to linq query its giving me thousands of record. I cant find the actual root cause of the problem can any one help me ...
sql query
select
DLId = p.Id,
TopicId = st.Id,
TopicName = at.Name,
PrimaryOrg = bo.BusinessUnit,
StatusId = ns.ID,
ModifiedBy = pa.LastName
from STopics st
join ATopics at on st.Id = at.Id
join Students p on st.StudentId = p.Id
join Sorgs sbu on at.BUorgID = sbu.BUOrgID
join BOrgs bo on sbu.BUOrgID = bo.ID
join Status ns on st.SID = ns.ID
join Students pa on st.NominatedBy = pa.Email
where p.IsActive = 1 and sbu.StudentID = 123 and sbu.IsActive = 1
and the linq query is
(from st in Context.STopics
join at in Context.ATopics on st.Id equals at.Id
join p in Context.Students on st.StudentId equals p.Id
join sbu in Context.Sorgs on at.BUorgID equals sbu.BUOrgID
join bo in Context.BOrgs on sbu.BUOrgID equals bo.ID
join ns in Context.Status on st.SID equals ns.ID
join pa in Context.Students on st.NominatedBy equals pa.Email
where p.IsActive==true && sbu.StudentID == 123 && sbu.IsActive == true
select new result()
{
DLId = p.Id,
TopicId = st.Id,
TopicName = at.Name,
PrimaryOrg = bo.BusinessUnit,
StatusId = ns.ID,
ModifiedBy = pa.LastName
})
(from st in Context.STopics
join at in Context.ATopics on st.Id equals at.Id
join p in Context.Students on new { st.StudentId, p.IsActive } equals new { p.Id , true}
join sbu in Context.Sorgs on new { sbu.BUorgID, sbu.IsActive,sbu.StudentID } equals new { at.BUorgID , true, 123}
join bo in Context.BOrgs on sbu.BUOrgID equals bo.ID
join ns in Context.Status on st.SID equals ns.ID
join pa in Context.Students on st.NominatedBy equals pa.Email
select new result()
{
DLId = p.Id,
TopicId = st.Id,
TopicName = at.Name,
PrimaryOrg = bo.BusinessUnit,
StatusId = ns.ID,
ModifiedBy = pa.LastName
})
Can you try this one, if you want to get exact issue, you can get how sql query is generated from the linq statements, linq query uses lots of inner query methodology
var query= your linqquery;
string sqlQuery=query.ToString();
you can review sqlQuery.

Query entity select, inner join and count

i want to translate this SQL query :
SELECT FirstName,LastName, WaiterId, Count(*) AS compte
FROM Waiter
INNER JOIN Client on Waiter.Id = Client.WaiterId
GROUP BY WaiterId,lastname, firstname
ORDER BY compte DESC;
in entity framework.
I tried something like this :
var query = (from w in db.Waiter
join c in db.Client on w.Id equals c.WaiterId
group c by c.WaiterId into g
//orderby
select new
{
WaiterId = g.Key,
count = g.Count()
});
but my select don't work. I can't select FirstName and LastName and i don't even know if my count is good.
You need to include all the properties in the group by.
var query = (from w in db.Waiter
join c in db.Client on w.Id equals c.WaiterId
group c by new { c.FirstName, c.LastName, c.WaiterId} into g
orderby g.Count() descending
select new
{
FirstName = g.Key.FirstName,
LastName = g.Key.LastName,
WaiterId = g.Key.WaiterId,
count = g.Count()
});

convert group by query to linq

I am trying to convert below query in linq
select ta.id, ta.name, min(tb.id) from tableA ta
left join tableB tb on tb.fkid=ta.id
group by ta.id, ta.name
I tried below
var query = (from tableA in tableARepository.AsQueryable()
join tableB in tableBRepository.AsQueryable() on
tableA.Id equals tableB.fkid
group grp by new {tableA.Id, tableA.Name } into groupedCol
select new
{
Id = groupedCol.Key.Id,
Name = groupedCol.Key.Name,
fkId = grouppedCol.Min // cant get column fkid from tableB
}
);
I am not able to get Min of column fkid of tableB
What is missing here or how can i fix this?
You should be able to get the results that you are looking for without using Join or GroupBy:
var restrictTo = new[] {1, 2};
var query = tableARepository.AsQueryable()
// I want to add where clause like tableA.Id in (1,2)
.Where(a => restrictTo.Contains(a.Id))
.Select(a => new {
Id = a.Id
, Name = a.Name
, FkId = tableBRepository.AsQueryable().Min(b => b.fkid=a.id)
});
I think you are looking for GroupJoin
from tableA in tableARepository.AsQueryable()
join tableB in tableBRepository.AsQueryable() on
tableA.Id equals tableB.fkid into tb
select new
{
Id = tableA.Id,
Name = tableA.Name,
fkId = tb.Min(x => x.id)
}

How do I change this query to linq to sql?

Query:
select emp.empname as Name, dep.depname as Department
from Employee as emp
inner join Department as dep on emp.depid=dep.depid
where emp.id='2'
How can I change this to linq to sql?
var id = 2;
var qry = from e in db.Employees
where e.Id == id
select new {
Name = e.EmpName,
Department = e.Department.DepName
};
(assumes the parent-association between employee and department is defined in the DBML)
and if you expect exactly one such:
var record = qry.Single();
Console.WriteLine(record.Name);
Console.WriteLine(record.Department);
Approximately:
from e in dc.Employee
join d in dc.Department on e.depid equals d.depid
where e.id == '2'
select new
{
Name = e.empname,
Department = d.depname
}
This is why LINQ is so great: there is no reason to even join with the Departments table to get it to work:
from employee in db.Employees
where employee.id == 2
select new
{
Name = employee.empname,
Department = employee.Department.depname
};

Categories

Resources