convert group by query to linq - c#

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)
}

Related

Correct sql to linq query

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
})
};

ANDing in JOIN Condition Using LINQ

I recently ran into some SQL code that looks like this
SELECT
a.Id,
b.Id,
c.Id,
d.Id,
b.Name,
d.Occupation,
FROM TableA a
JOIN TableB b ON a.Id = b.Id
JOIN TableC c ON b.Id = c.Id AND b.Name = a.Name
JOIN tableD d ON c.Id = d.Id AND c.Occupation = d.Occupation
I've never used ANDs inside JOINs like this in a corresponding LINQ query (for context, I use the Entity Framework and LINQ for all of my queries). I usually put all my ANDs inside there where clause like this:
var query = from a in dbContext.TableA
join b in dbContext.TableB on a.Id equals b.Id
join c in dbContext.TableC on b.Id equals c.Id
join d in dbContext.TableD on c.Id equals d.Id
where b.Name = a.Name
where c.Occupation = d.Occupation
select new
{
AId = a.Id,
BId = b.Id,
CId = c.Id,
DId = d.Id,
BName = b.Name,
DOccupation = d.Occupation,
};
What technique can I use to get my LINQ query to match the SQL statement above?
You can join on multiple properties by constructing anonymous types from your properties like this:
var query = from a in dbContext.TableA
join b in dbContext.TableB on new { a.Id, a.Name } equals new { b.Id, b.Name }
join c in dbContext.TableC on b.Id equals c.Id
join d in dbContext.TableD on new { c.Id, c.Occupation } equals new { d.Id, d.Occupation }
select new
{
AId = a.Id,
BId = b.Id,
CId = c.Id,
DId = d.Id,
BName = b.Name,
DOccupation = d.Occupation,
};
Note that the name, order, and datatype of each property in the anonymous types need to be the same on both sides of the equals in order for this to work. Otherwise they would be two different anonymous types and would not be equatable.

Linq: Select from 2 datatable where column id from first table = column id from second table

The SQL would be something like
select GeneralData.id, GeneralData.name, GeneralData.last_name, Student.id
from GeneralData Inner JOIN Student ON Student.id=GeneralData.id
GeneralData is dt1
Student is dt2
what I want to get is dt3
have some proposals?
var query =
from s in db.Student
from g in db.GeneralData
where s.id == g.id
select new
{
g.id,
g.name,
g.last_name
};
var query = from data in dc.GeneralData
join stud in dc.Students in data.id equals stud.id
select new
{
data.id, data.Name, data.LastName, stud.id
};
Something like this:
var result= (
from general in db.GeneralData
join student in db.Student
on general.id=student.id
select new
{
general.id,
general.name,
general.last_name,
studentId=student.id
}
);
where db is the linq data context
As a method chain:
dt2.Where(s=>s.id == 1)
.Select(s=> new {Stud = s, Data= dt1.Where(g=>g.id == s.id)}).First()
.Select(q=> new {q.Stud.id, q.Data.name, q.data.last_name}).FirstOrDefault();

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
};

Entity Framework Many-To-Many + Count

I have three tables, Professors, ProfessorStudent, Student.
I want all Professors + How many Students each Professor have.
I can do this:
context.ProfessorSet.Include("Student")
context.ProfessorSet.Include("Student").ToList() will read all three tables.
But i dont wanna get Student table, I want that Linq just get "Professor Table"+ "Count(*) ProfessorStudent Group By StudentId".
Its possible?
I do using this:
var c = from tag in contexto.ProfessorSet
select new
{
Tag = tag,
Count = tag.Student.Count
};
But generate this SQL:
SELECT
C.Id,
C.Nome,
C.C1
FROM
(SELECT
A.Id,
A.Nome,
(SELECT
COUNT(0)
FROM ProfessorStudant AS B
WHERE A.Id = B.ProfessorId
) AS [C1]
FROM Professor AS A)
I want this:
Select A.Id, Count(0) from Professor A
inner join ProfessorStudent B on A.Id = B.ProfessorId
Group By A.Id
from p in context.ProfessorSet
from s in p.Student
group s by s.StudentId into g
select new
{
Professor = p,
StudentCounts = from sc in g
select new
{
StudentId = sc.Key,
Count = sc.Group.Count()
}
}

Categories

Resources