Equivalent LINQ to SQL query - linq-to-sql

Can anyone help me with the equivalent LINQ query for the SQL below?
I am new to LINQ
Select * From Students_History SH
Where SH.Active = 1 and SH.ModifiedAt in (
select MAX(SH1.ModifiedAt)from Students_History SH1
group by SH1.StudentId)
This is what I have tried
var q =
from h in Students_History
where h.Active=1
group h by h.StudentId into g
select new
{
StudentID = g.Key,
LatestModified = g.Max (x => x.ModifiedAt)
}
This linq query does not give me the right result and somehow the active=1 is ignored
I have about dozen fields in my Students_History table and I want all those fields not just studentId and ModifiedAt.

Try this:
var q =
from hg in Students_History
group hg by hg.StudentId into g
join h in Students_History on g.Key equals h.StudentId
where h.Active == 1 && h.ModifiedAt == g.Max(x => x.ModifiedAt)
select new
{
StudentID = h.StudentId,
LatestModified = h.ModifiedAt
}

You need to compare using the == operator.

Related

LINQ Query with join, group by and Sum()

I've working on this for a while so I thought I'd post here to see if anyone has any idea how a query like the following can be converted to LINQ.
Here is the MySQL Query:
SELECT SUM(line_ord.itemqty) AS LineOrderQTY, SUM(assemblyNumber.qty) AS
AssemblyQTY FROM line_ord
LEFT JOIN
(
SELECT sum(assemblyno.qty) AS qty, assemblyno.row_id FROM assemblyno
INNER JOIN line_ord ON assemblyno.row_id = line_ord.row_id
WHERE line_ord.bdnum = 'S61460'
) AS assemblyNumber ON line_ord.row_id = assemblyNumber.row_id
WHERE line_ord.bdnum = 'S61460'
This what I have so far for the LINQ query, but it doesn't return the proper results.
var items = (from c in Context.OrderLineItemData
join e in Context.AssemblyLabelData on c.ID equals e.RowID
where c.BreakdownNumber == breakdownNumber
group c by c.BreakdownNumber into g
select new
{
AssemblyQuantity= g.Sum(x => x.Quantity),
LineOrdQuantity = g.Sum(**WHAT GOES HERE?**)
}).FirstOrDefault()
I did manage to get it to work like this, but it seems kind of messy to me.
var items = (from c in Context.OrderLineItemData
join e in Context.AssemblyLabelData on c.ID equals e.RowID
where c.BreakdownNumber == breakdownNumber
group c by c into g
select new
{
AssemblyQuantity= g.Sum(x => x.Quantity),
LineOrdQuantity = (from e in Context.OrderLineItemData where e.BreakdownNumber == breakdownNumber select e.Quantity).Sum()
}).FirstOrDefault();
Is there a better way to do this?
Got my answer. Seems like a query object has to be created and then I can use it to preform my calculations.
var items = (from od in Context.OrderLineItemData
join ad in Context.AssemblyLabelData on od.ID equals ad.RowID into odGroup
from g in odGroup.DefaultIfEmpty()
where od.BreakdownNumber == breakdownNumber
group g by new
{
breakdown = od.BreakdownNumber,
LineOrd = od,
AssemblyQty = g == null ? 0 : g.Quantity
}
into groupped
select new
{
Breakdown = groupped.Key.breakdown,
AssemblyQty = groupped.Sum(x => x.Quantity),
lineOrdQty = groupped.Key.LineOrd.Quantity
}
);
int remainingQuantity = items.Sum(x => x.lineOrdQty) - items.Sum(x => x.AssemblyQty);

GroupBy LINQ to SQL not working, perhaps

I'm struggling to get groupby working in LINQ to SQL, im pretty new to it...I trying to groupby g.id but it just wont work...any help would be greatly appreciated...Cheers
IQueryable<GuestList> query = from t in _ttx.Trips
join l in _ttx.Legs on t.Id equals l.TripId
join gl in _ttx.GuestLegs on l.Id equals gl.LegId
join g in _ttx.Guests on gl.GuestId equals g.Id
where t.Id == id
select new GuestList()
{
Id = g.Id,
Name = g.Name,
NoOfLegs = g.GuestLegs.Count()
};
My result is
1 paul 3
2 Jim 1
1 paul 3
1 paul 3
Please try is as below.
var query2 = (from ps in query
group ps by new { ps.Id } into prod
select new GuestList
{
Id = prod.Key.Id,
Name = prod.Name,
NoOfLegs = prod.Sum(c => c.NoOfLegs),
}).OrderBy(x => x.Id).ToList();

Join two tables using LINQ Query and order based two parameters

I have two tables Customers and Orders. I want a LINQ query to fetch list of all the orders placed by all the customers organized first by month and then by year. If there is no order corresponding to the customer, "No Orders” should be displayed.
The columns of Customers table are
customer_id
name
city
The columns of Orders table are
order_id
order_date
order_total
customer_id
I tried writing it the following way but its not giving complete output.
var res = from cust in db.Customers
join ord in db.Orders
on cust.customer_id equals ord.customer_id into g
from d in g.DefaultIfEmpty()
select new {
name=cust.name,
oId=d.order_id==null?-1:d.order_id
};
How do I rectify it?
I finally got the right answer which exactly the result as expected. I have put it below. I have used two LINQ queries to arrive at the result though. The first one gives the result, but the final result needs to be displayed with names of customer and their order totals, hence it is partial result. The second LINQ query further refines the 'partialResult' and gives the result as expected.
var partialResult = (from c in db.Customers
join o in db.Orders
on c.customer_id equals o.customer_id
select new
{c.name,
o.order_total,
o.order_date }).OrderBy(m => m.order_date.Month).ThenBy(y => y.order_date.Year);
var finalResult = from c in db.Customers
orderby c.name
select new
{
name = c.name,
list = (from r in partialResult where c.name == r.name select r.order_total).ToList()
};
foreach (var item in finalResult)
{
Console.WriteLine(item.name);
if (item.list.Count == 0)
{
Console.WriteLine("No orders");
}
else
{
foreach (var i in item.list)
{
Console.WriteLine(i);
}
}
}
Something like this. You can do it using LINQ Predicates
var res = Customers.Join(Orders, x => x.customer_id, y => y.customer_id, (x, y) => x).ToList();
This is what you can do:
var res = from cust in db.Customers
join ord in db.Orders
on cust.customer_id equals ord.customer_id into g
from d in g.DefaultIfEmpty()
orderby d.OrderDate.Year, d.OrderDate.Month
select new {
name=cust.name,
oId = d.order_id.ToString() ?? "No Orders"
};

Linq to SQL using IQueryable API for 1 to many relationship

Assume A is a parent table with many B records. Essentially I need LINQ to SQL to generate this query:
Select * from A
Join B n on B.Id = A.Id
where A.OtherId in (0,1,2,3)
and B.DateTime >= '2011-02-03 00:30:00.000'
and A.TypeId = 1
order by B.DateTime
The LINQ I have looks like this:
List<string> programIds = new List<string>("0", "1", "2", "3");
IQueryable<A> query = db.As;
query = query.Where(a => programIds.Contains(a.ProgramId));
query = query.Where(a => a.B.Any(b => b.DateTime >= ('2011-02-03 00:30:00.000')));
The problem begins on this last statement, the generated query then looks like this:
?query
{SELECT *
FROM [dbo].[A] AS [A]
WHERE (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[B] AS [B]
WHERE ([B].[AirsOnStartDateTime] >= #p0) AND ([B].[Id] = [A].[Id])
)) AND ((CONVERT(BigInt,[A].[OtherId])) IN (#p1, #p2, #p3, #p4))
}
Any ideas?
Sorry, I'm typing this up in notepad and can't verify the syntax at the moment, but I think something like this is what you are looking for:
List<string> programIds = new List<string>("0", "1", "2", "3");
var query = from a in db.As
from b in db.Bs
where programIds.Contains(a.ProgramID)
&& a.TypeID == 1
&& a.ID == b.ID
&& b.DateTime >= ('2011-02-03 00:30:00.000')
select new
{
a....
b....
....
}
Just fill in the fields you want to return in the anonymous type select section.
Also, I made an assumption on the db.Bs being the way to get the B values out of your table... Fix that as appropriate.

Linq Query - how can you improve the following query?

I have a Linq To Sql query in my asp.net website.
This query works too Slow and im sure that it can be improved.
Can anyone help me ReWrite this query?
I assume using "join" would make it quicker but couldn't get it right. :(
Here is the query: (input params : INT_GENDER )
var users = from u in db.Users
where (u.gender == INT_GENDER) && (u.age > 25)
let fileId = (from f in db.Files
where f.username == u.username && f.approved
orderby f.primary
select f.id).FirstOrDefault()
let answer = (from a in db.Answers
where (a.username == u.username) &&
(a.q_id == (from q in db.Questions where q.type == 1
select q.id).FirstOrDefault()) &&
a.approved
select a).FirstOrDefault()
select new {
Username = u.u_username,
FileId = fileId !=null ? fileId : GetEmptyFileId(),
Answer = (answer == null ? "" : (answer.approved ? answer.value: "Empty"))
};
Query is based on 3 tables.
Tables :
1. Users
2. Files
3. Answers
Username column in the users table is identity.
Each user can have many or none Files
Each user can have many or none Answers.
Thank you!
Dan
Here is my modest attempt to decipher this in plain T-SQL. Hope this helps.
SELECT u.username, f.id, a.value, a.approved
FROM users AS u
JOIN files AS f ON u.username = f.username
JOIN answers AS a ON a.username = u.username
JOIN questions AS q ON a.q_id = q.id
WHERE u.gender = #INT_GENDER
AND u.age > 25
AND f.approved = 1
AND a.approved = 1
AND q.type = 1