How to use MAX in subquery in LINQ - linq

I am trying to write my first query in LINQ
This is my SQL query
SELECT P.id,PS.Id,P.CPersonName
,PS.StartDate FROM Provider P
LEFT OUTER JOIN ProviderSubscription PS ON
P.id=PS.providerID
AND PS.Id=(SELECT max(id)from ProviderSubscription where
providerSubscription.ProviderId=Provider.id)
And so far i wrote this LINQ.
var query = (from p in db.Providers
join ps in db.ProviderSubscriptions on p.Id
equals ps.ProviderId
select new ViewModel
{
providerid = p.Id,
providername = p.ProviderName,
subscriptiondate = ps.ExpiryDate,
}).ToList();
I am unable to add this part in my LINQ.
AND PS.Id=(SELECT max(id)from ProviderSubscription where
providerSubscription.ProviderId=Provider.id)

I don't think you need a subquery, when you're doing a join with same tables and with same conditions then there is NO need to again write an inner query with same tables. Below query should return same result:
var query = (from p in db.Providers
join ps in db.ProviderSubscriptions on p.Id equals ps.ProviderId
where ps.Contains(ps.Max(u=>u.id))
select new ViewModel
{
providerid = p.Id,
providername = p.ProviderName,
subscriptiondate = ps.ExpiryDate,
}).ToList();

Related

Need help converting SQL into LINQ

SELECT ra.ResidentID, ra.RoomID, r.Number, ra.StartDate, p.FacilityID
FROM(
SELECT ResidentID, MAX(StartDate) AS max_start
FROM RoomAssignments
GROUP BY ResidentID
) m
INNER JOIN RoomAssignments ra
ON ra.ResidentID = m.ResidentID
AND ra.StartDate = m.max_start
INNER JOIN Rooms r
ON r.ID = ra.RoomID
INNER JOIN Person p
ON p.ID = ra.ResidentID
inner join ComplianceStage cs
ON cs.Id = p.ComplianceStageID
ORDER BY ra.EndDate DESC
I'm trying to figure out how to convert this to C# using LINQ. I'm brand new with C# and LINQ and can't get my subquery to fire correctly. Any chance one of you wizards can turn the lights on for me?
Update-----------------
I think I've got the jist of it, but am having trouble querying for the max startdate:
var maxQuery =
from mra in RoomAssignments
group mra by mra.ResidentID
select new { mra.ResidentID, mra.StartDate.Max() };
from ra in RoomAssignments
join r in Rooms on ra.RoomID equals r.ID
join p in Persons on ra.ResidentID equals p.ID
where ra.ResidentID == maxQuery.ResidentID
where ra.StartDate == maxQuery.StartDate
orderby ra.ResidentID, ra.StartDate descending
select new {ra.ResidentID, ra.RoomID, r.Number, ra.StartDate, p.FacilityID}
Following my LINQ to SQL Recipe, the conversion is pretty straight forward if you just follow the SQL. The only tricky part is joining the range variable from the subquery for max start date to a new anonymous object from RoomAssignments that matches the field names.
var maxQuery = from mra in RoomAssignments
group mra by mra.ResidentID into mrag
select new { ResidentID = mrag.Key, MaxStart = mrag.Max(mra => mra.StartDate) };
var ans = from m in maxQuery
join ra in RoomAssignments on m equals new { ra.ResidentID, MaxStart = ra.StartDate }
join r in Rooms on ra.RoomID equals r.ID
join p in Persons on ra.ResidentID equals p.ID
join cs in ComplianceStage on p.ComplianceStageID equals cs.Id
orderby ra.EndDate descending
select new {
ra.ResidentID,
ra.RoomID,
r.Number,
ra.StartDate,
p.FacilityID
};

Issue with Group by clause in linq to sql

I want to make this query in linq to sql .
Please help. I am new to linq and having problem to with the group by clause .
Here is the sql query
select count(USERID), d.DEPTNAME from USERS u
join department d on u.DEPTID = d.DEPTID
group by u.DEPTID, d.DEPTNAME
A more direct translation would be like this:
var query =
from u in db.Users
join d in db.Departments on u.DeptId equals d.DeptId
group d by new { d.DeptId, d.DeptName } into g
select new
{
g.Key.DeptName,
Count = g.Count(),
};
Though I think it would be better off written like this:
// looks like we're counting users in each department
var query =
from d in db.Departments
select new
{
d.DeptName,
Count = db.Users.Count(u => u.DeptId == d.DeptId),
};

Linq Nested Inner Joins

I want to join the following Tables
1. B_Book[1st Table]
-B_BID (Book ID)(PK)
-B_Name
-B_CategroyID (FK)
2. BI_BookInstance [2nd Table]
-BI_IID(Instance ID)
-BI_BID (FK)
-BI_Price
3. BC_BookCategory [3rd Table]
-BC_CategoryID (PK)
-BC_CategoryName
First Join B_Book and BI_BookInstance then join the result of those both with BookCategory.
(1st join)[B_BID equals BI_BID]
(2nd nested join)[result of 1st join B_CategoryID equals BC_CategoryID]
Edit
SQL would be something like the following:
SELECT * FROM
(SELECT * FROM B_Book b JOIN BI_BookInstance bi on b.B_BID = bi.BI_BID) as t1
JOIN BC_BookCategoryID bc on bc.BC_CategoryID = t1.B_CategoryID
What matches your query in LINQ would be the following (and you'll notice the similarity with SQL). I've also included some examples on how to rename the fields returned, such as Price or CategoryName:
var results = from b in B_Book
join bi in BI_BookInstance
on b.B_BID equals bi.BI_BID
join bc in BC_BookCategory
on b.B_CategoryID equals bc.BC_CategoryID
select new
{
// put in whatever fields you want returned here:
b.B_BID,
b.B_CategoryID,
b.B_Name,
bi.BI_BID,
bi.BI_IID,
Price = bi.BI_Price,
bc.BC_CategoryID,
CategoryName = bc.BC_CategoryName
};
I have supposed inner joins (your FKs is not null), so i would like query like this:
var ctx = new YourEntities();
var query = from b in ctx.B_Book
from bi in ctx.BI_BookInstance
from bc in ctx.BC_BookCategory
where b.B_BID == bi.BI_BID && b.B_CategoryID == bc.BC_CategoryID
select new
{
BInstID = bi.BI_IID,
BName = b.B_Name,
BPrice = bi.BI_Price,
BCategory = bc.BC_CategoryName
};
foreach (var item in query)
{
Console.WriteLine(item.BInstID);
Console.WriteLine(item.BName);
Console.WriteLine(item.BPrice);
Console.WriteLine(item.BCategory);
Console.WriteLine("");
}
You can do this without explicitly using linq's join statement, provided that navigation properties are in place:
from b in ctx.B_Book
from bi in b.BookInstances
select new { b.Property1, bi.Property2, b.BookCategory.Name }

Join statement in Linq to Sql

I need to write Join statment after writing query in linq
example :
var Query = (from Tab in Db.Employees
select Tab)
as i have some cases to perform join operation so
i need to do it on this Query Query.Join(Join with another Table like Department); I need the Syntax
if (DeptID != -1){ Query.Join(Join with table Department where FkDeptID = DeptID); }
Consider the usage of join in the LINQ 'query syntax':
from t1 in db.Table1
join t2 in db.Table2 on t1.field equals t2.field
select new { t1.field2, t2.field3}
Something like this?
var results = (from q in Query
join m in myList on q.SomeID = m.SomeID
select unknown);
Try using this query:
var Query =
from e in Db.Employees
join d in Db.Departments on e.FkDeptID equals d.DeptID into departments
select new
{
Employee = e,
Department = departments.SingleOrDefault(),
};
This works assuming that when e.FkDeptID == -1 that there is no record in the Departments table and in that case Department would be assigned null.
You should never have more than one department for an employee so I've used SingleOrDefault rather than FirstOrDefault.

linq join table with collection

I have a collection that I'm gathering from a linq query and I'd like to use that collection as a join for another query. How do I do that?
Thanks
LINQ 101 Samples
Copied LINQ statements from here
string[] categories = new string[]{
"Beverages",
"Condiments",
"Vegetables",
"Dairy Products",
"Seafood" };
List<Product> products = GetProductList();
var q =
from c in categories
join p in products on c equals p.Category
select new { Category = c, p.ProductName };
foreach (var v in q)
{
Console.WriteLine(v.ProductName + ": " + v.Category);
}
Try this
var query2 = from c in db.YourTable
join q in query1 on c.Id equals q.Id
select c;
Where query1 wats your first collection that originated from a linq query.
You should be able to do this:
List<Product> products = GetProductList(); //collection
var q = from c in categories
join p in products on c equals p.Category into ps
select new { Category = c, Products = ps };
Below is a Linq query I wrote that does exactly that. This is a Linq to SQL query that joins in a local collection.
int[] keyList = new int[] { 7064, 7065, 6242 };
var query = (from child in ETAModule
join parent in ETA on child.ExpID equals parent.ExpID
where child.ID >= 65490442
where keyList.Contains(child.ExpID)
orderby child.ID
select new { EtaModule = child, Eta = parent });
...not a whole lot of information provided, but here is a very simple example.
var firstCollection = List<YourClassNameHere>(); // this is your pre-existing collection
var results = from o in firstCollection
join i in SomeOtherCollection on o.JoinField equals i.JoinField
select i; // or whatever you like

Resources