Join statement in Linq to Sql - linq

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.

Related

Linq query not returning expected results even when using DefaultIfEmpty

I have the following query in one of my Entity Framework Core API controllers:
var plotData = await (from nl in _context.BookList
join ql in _context.PlotList on nl.PlotId equals ql.PlotId
join qc in _context.PlotChoices on ql.PlotId equals qc.PlotId
join nk in _context.BookLinks.DefaultIfEmpty() on qc.ChoiceId equals nk.ChoiceId
where nl.Id == ID
select new
{ .. }
I need it to return all rows even if data doesn't exist in the BookLinks table.
However, it's not returning rows if there is no data data in the BookLinks table for that row.
But this SQL query, from which I'm trying to model from, does return data...it returns nulls if there is no data in BookLinks.
select * from BookList bl
left join PlotList pl ON bl.plotId = bl.plotId
left join PlotChoices pc ON pl.plotId = pc.plotId
left join BookLinks bk ON pc.choiceID = bk.choiceID
where nl.caseID = '2abv1'
From what I read online, adding 'DefaultIfEmpty()' to the end of BookLinks should fix that, but it hasn't.
What am I doing wrong?
Thanks!
When using left join , you can try below code sample :
var plotData = (from nl in _context.BookList
join ql in _context.PlotList on nl.PlotId equals ql.PlotId
join qc in _context.PlotChoices on ql.PlotId equals qc.PlotId
join nk in _context.BookLinks on qc.ChoiceId equals nk.ChoiceId into Details
from m in Details.DefaultIfEmpty()
where nl.Id == ID
select new
{
}).ToList();

How to use MAX in subquery in 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();

Linq Group by / Distinct with Join table

i plan to join 2 table, and get the distinct value of language column. How should i achieve that in Linq? I try add 'group' but no luck. Besides, i want to select s value too together with r distinct language value.
My code:
public ActionResult QuestionLink(int Survey_ID)
{
var query = from r in db.SURV_Question_Ext_Model
join s in db.SURV_Question_Model
on r.Qext_Question_ID equals s.Question_ID
where s.Question_Survey_ID == Survey_ID
group r.language << this is not work **
select r;
return PartialView(query.ToList());
}
This is what in MoreLinq is called DistinctBy. But if that method works on IEnumerable, so you can't use it in an EF query. But you can use the same approach:
var query = from r in db.SURV_Question_Ext_Model
join s in db.SURV_Question_Model on r.Qext_Question_ID equals s.Question_ID
where s.Question_Survey_ID == Survey_ID
group new { r, s } by r.language into grp
select grp.FirstOrDefault();
But I wonder if this really is what you want. The result depends on the ordering of languages that the database happens to return. I think you should add a predicate for a specific language and remove the grouping:
var query = from r in db.SURV_Question_Ext_Model
join s in db.SURV_Question_Model
on r.Qext_Question_ID equals s.Question_ID
where s.Question_Survey_ID == Survey_ID
&& r.language == someVariable
select new { r, s };
You can do like this:
var query = from r in db.SURV_Question_Ext_Model
join s in db.SURV_Question_Model
on r.Qext_Question_ID equals s.Question_ID
where s.Question_Survey_ID == Survey_ID
group new {r, s} by r.language into rg
select rg.Key;

Linq subtraction sum(values) from two tables

I have two db.Table1 and db.Table2 with columns named IdUser,Value
I think I should have some join but i miss the logic
it's just a logic it's not a code
how can do something like :
var total = Sum(db.Table1(Sum(Value))-db.Table2(Sum(Value))
.Where(db.Table1.IdUser=db.Table2.IdUser)
Join the tables and group
var total = from table1record in Table1
join table2record in Table2 on table1Record.IdUser equals table2Record.IdUser
group new { table1record,table2record } by table1record.IdUser into groupedRecords
select groupedRecords.Sum(x=>x.Table1Value) - groupedRecords.Sum(x=>x.Table2Value);

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 }

Resources