How to Join 3 Table in LINQ using Method Syntax - c#

I have joined two tables in method syntax using Except method. and written another query to join third table because I dont have more than 1 common columns to select. SO, I want to combine these two queries into one using Method syntax.
Note that, I have to use method sytanx in linq and Except() is must..
var EResult = dbContext.Table1.Where(x => x.ID >= 5
&& x.TID == 1
&& x.SID == rModel.SID)
.Select(s => s.ID)
.Except(dbContext.Table2.Select(s => s.ID))
.ToList();
List<rModel> Result = (from t1 in dbContext.Table1
join t3 in dbContext.Table3 on t1.BID equals t3.BID
where EResult.Contains(t1.ID)
select new RTableModel
{
ID = t1.ID,
SCode = t1.SCode,
time = t1.time.ToString(),
.
.......
}
Here the problem is, I am accessing table 1 twice so I want to combine it into single query using method syntax and here Except() is must..
How to Combine these two queries into one?

Use this command:
List<rModel> Result = (from t1 in dbContext.Table1
join t3 in dbContext.Table3 on t1.BID equals t3.BID
where (t1.ID >= 5 && t1.TID == 1 && t1.SID == rModel.SID
&& !dbContext.Table2.Select(s => s.ID).Contains(t1.ID))
select new RTableModel
{
ID = t1.ID,
SCode = t1.SCode,
time = t1.time.ToString()
}
or simply put table2 ids into a variable:
var ids = dbContext.Table2.Select(s => s.ID).ToList();
and use:
List<rModel> Result = (from t1 in dbContext.Table1
join t3 in dbContext.Table3 on t1.BID equals t3.BID
where (t1.ID >= 5 && t1.TID == 1 && t1.SID == rModel.SID
&& !ids.Contains(t1.ID))
select new RTableModel
{
ID = t1.ID,
SCode = t1.SCode,
time = t1.time.ToString()
}
Using Except doesn't helps you as it's argument should be the same type of your collection but here is an example of using Except:
List<rModel> Result = (from t1 in dbContext.Table1
join t3 in dbContext.Table3 on t1.BID equals t3.BID
where (t1.ID >= 5 && t1.TID == 1 && t1.SID == rModel.SID)
select new RTableModel
{
ID = t1.ID,
SCode = t1.SCode,
time = t1.time.ToString()
}
Result = Result.Except(Result.Where(P => ids.Contains(P.ID)));
This will give accurate result

Related

Improve LINQ query performance. A query with "joins" or small queries?

I get the ids of 2 tables and use them to verify if there is a record in a third table.
Summary structure tables:
Table 1 (int id1 and string UserName);
Table 2 (int id2 and string BranchName);
Table 3 (int Id_User and int Id_Branch);//fk table 1 and 2
Code:
...
string user = "NAME1";
string branch = "BRANCH1";
using (A_Entities context= new A_Entities())
{
//Get user id
var res1 = context.Table1.SingleOrDefault(x => x.UserName == user);
int idUser = res1 != null ? res1.id1 : 0;
//Get branch id
var res2 = context.Table2.SingleOrDefault(x => x.BranchName == branch);
int idBranch = res2 != null ? res2.id2 : 0;
//Validate
var res3 = context.Table3.SingleOrDefault(x => x.Id_User == idUser && x.Id_Branch == idBranch);
bool result = res3 != null ? true : false;
}
...
This code structure works correctly and I use it several times (5 approx.) with different tables before showing a result.
To be able to perform performance tests and compare, can you help me generate a unified query? (maybe with joins)
This should combine the queries into one. I used lambda syntax since you started with that, though I think in this case fluent syntax may be easier to follow:
var result = (context.Table3.Join(context.Table1, t3 => t3.Id_User, t1 => t1.id1, (t3, t1) => new { t3, t1 })
.Join(context.Table2, t3t1 => t3t1.t3.Id_Branch, t2 => t2.id2, (t3t1, t2) => new { t3t1.t3, t3t1.t1, t2 })
.Where(t3t1t2 => t3t1t2.t1.UserName == user && t3t1t2.t2.BranchName == branch)
)
.Any();
Here is the query syntax equivalent:
var res2 = (from t3 in context.Table3
join t1 in context.Table1 on t3.Id_User equals t1.id1
join t2 in context.Table2 on t3.Id_Branch equals t2.id2
where t1.UserName == user && t2.BranchName == branch
select t3
)
.Any();

Converting an SQL Containing inner and Outer Joins into Linq

I need to convert an SQL query to Linq/Lambda expression, I am trying doing the same but not getting the desired results.
SQL:
SELECT b.*, n.notes
FROM Goal_Allocation_Branch as b
INNER JOIN Goal_Allocation_Product as g
on b.Product = g.ProductID
and b.Year = g.Year
left join Goal_Allocation_Branch_Notes as n
on b.branchnumber = n.branch
and n.year = ddlYear
WHERE b.Year = ddlYear
and g.Show = 1
and branchnumber = ddlBranch
I am new to Linq , I am getting error on Join Clause , and X is not containing any data from first Join
var result = (from br in _DB_Branches.Goal_Allocation_Branches
join pr in _DB_Product.Goal_Allocation_Products on new { br.Product, br.Year } equals new {Product= pr.ProductID, Year= pr.Year }
join n in _DB_Notes.Goal_Allocation_Branch_Notes.Where(n => n.Year == ddlYear) on br.BranchNumber equals n.Branch into Notes
from x in Notes.DefaultIfEmpty()
select new BranchNotesViewModel
{
Year = x.Year,
BranchNumber = x.Branch,
ProductID = x.ProdID
}
).ToList();
Update: My First Join clause initially giving error "The type of one of the expression in Join Clause is incorrect " is resolved, when I Changed On Clause
from
"on new { br.Product, br.Year } equals new {pr.ProductID, pr.Year}"
"on new { br.Product, br.Year } equals new {Product=pr.ProductID,Year= pr.Year}"
still not getting desired results as expected from above SQL query. Please advise..
It should be something like this (see note):
var result =
(from br in _DB_Branches.Goal_Allocation_Branches
join pr in _DB_Product.Goal_Allocation_Products
on br.Product equals pr.ProductID
from n in _DB_Notes.Goal_Allocation_Branch_Notes.Where(x=>
x.branch == br.branchnumber
&& x.year == ddlYear
).DefaultIfEmpty()
where
br.Year == ddlYear
&& and br.Year == pr.Year
&& pr.Show == 1
&& br.branchnumber == ddlBranch
select new BranchNotesViewModel
{
Year = ...,
BranchNumber = ...,
ProductID = ...
}
).ToList();
Note: Change the select, to the properties you want.
Edit: fixed some syntax errors.
I finally figured out the correct answer. Working absolutely fine
var result = (from br in _DB_Branches.Goal_Allocation_Branches
join pr in _DB_Product.Goal_Allocation_Products on new { br.Product, br.Year } equals new { Product = pr.ProductID, Year = pr.Year }
join n in _DB_Notes.Goal_Allocation_Branch_Notes.Where(n=>n.Year==ddlYear) on br.BranchNumber equals n.Branch into Notes
where br.Year==ddlYear
&& pr.Show== true
&& br.BranchNumber==ddlBranch
from x in Notes.DefaultIfEmpty()
select new BranchNotesViewModel
{
Year=x.Year,
BranchNumber=x.Branch,
ProductID=br.Product,
Notes = x.Notes,
//All other fields needed
}
).ToList();

LINQ Case-Switch in Where Query

from what I can see it is possible to include the logic of a case-switch in a LINQ query but I cannot seem to figure out how to do it.
Basically I have three possible situations in which I want a Where clause to be different. The parameter that I take in is actually an int which can be 1, 2, or 3 so I just need to somehow correlate that to my where clause.
Thank you!
var parameter = Int32.Parse(Filter);
var queryString =
from m in db.Movies
join me in db.MovieEmployees
on m.ID equals me.movieID
join e in db.Employees
on me.employeeID equals e.ID
join r in db.Roles
on me.roleID equals r.ID
//when parameter = 1
where m.Name.Contains(searchString)
//when parameter = 2
where e.Name.Contains(searchString)
//when parameter = 3
where r.RoleType.Contains(searchString)
select new StarringViewModel { employeeID = e.ID, movieID = m.ID, roleID = r.ID };
return View(queryString.Distinct().ToList().OrderBy(x => x.movieName));
Try this
where (parameter == 1 && m.Name.Contains(searchString))
//when parameter = 2
|| (parameter == 2 && e.Name.Contains(searchString))
//when parameter = 3
|| (parameter == 3 && r.RoleType.Contains(searchString))

How can i use a where clause within a select statement in linq. (ie. on a property.)

I have this linq query:
var sku = (from a in con.MagentoStockBalances
join b in con.MFGParts on a.SKU equals b.mfgPartKey
join c in con.DCInventory_Currents on b.mfgPartKey equals c.mfgPartKey
where a.SKU != 0 && c.dcKey ==6
select new
{
Part_Number = b.mfgPartNumber,
Stock = a.stockBalance,
Recomended = a.RecomendedStock,
Cato = c.totalOnHandQuantity
}).ToList();
Now i need to remove the c.dcKey ==6 condition and have something like this:
var sku = (from a in con.MagentoStockBalances
join b in con.MFGParts on a.SKU equals b.mfgPartKey
join c in con.DCInventory_Currents on b.mfgPartKey equals c.mfgPartKey
where a.SKU != 0
select new
{
Part_Number = b.mfgPartNumber,
Stock = a.stockBalance,
Recomended = a.RecomendedStock,
Cato = c.totalOnHandQuantity where c.dcKey == 6,
Kerry = c.totalOnHandQuantity where c.dcKey == 7
}).ToList();
Something like this:
Cato = c.dcKey == 6 ? c.totalOnHandQuantity : 0,
Kerry = c.dcKey == 7 ? c.totalOnHandQuantity : 0
The ?: syntax is called a conditional operator.
Instead of adding another join, I would use a separate query in a let:
from a in con.MagentoStockBalances
join b in con.MFGParts on a.SKU equals b.mfgPartKey
where a.SKU != 0
let cs = con.DCInventory_Currents.Where(c => b.mfgPartKey == c.mfgPartKey)
select new
{
Part_Number = b.mfgPartNumber,
Stock = a.stockBalance,
Recomended = a.RecomendedStock,
Cato = cs.Single(c => c.dcKey == 6).totalOnHandQuantity
Kerry = cs.Single(c => c.dcKey == 7).totalOnHandQuantity
}
Though I have no idea how well will LINQ to SQL handle a query like this (if it handles it at all).
var query= from x in context.a
where String.IsNullOrEmpty(param1) || (x.p == param1 && x.i == param2)
select x;

Linq to Entity Join table with multiple OR conditions

I need to write a Linq-Entity state that can get the below SQL query
SELECT RR.OrderId
FROM dbo.TableOne RR
JOIN dbo.TableTwo M ON RR.OrderedProductId = M.ProductID OR RR.SoldProductId= M.ProductID
WHERE RR.StatusID IN ( 1, 4, 5, 6, 7 )
I am stuck with the below syntax
int[] statusIds = new int[] { 1, 4, 5, 6, 7 };
using (Entities context = new Entities())
{
var query = (from RR in context.TableOne
join M in context.TableTwo on new { RR.OrderedProductId, RR.SoldProductId} equals new { M.ProductID }
where RR.CustomerID == CustomerID
&& statusIds.Any(x => x.Equals(RR.StatusID.Value))
select RR.OrderId).ToArray();
}
this gives me below error
Error 50 The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.
How can I do a Multiple condition join for a table.
You don't have to use the join syntax. Adding the predicates in a where clause has the same effect and you can add more conditions:
var query = (from RR in context.TableOne
from M in context.TableTwo
where RR.OrderedProductId == M.ProductID
|| RR.SoldProductId == M.ProductID // Your join
where RR.CustomerID == CustomerID
&& statusIds.Any(x => x.Equals(RR.StatusID.Value))
select RR.OrderId).ToArray();
Change your query syntax from using join to using an additional from clause
var query = (from RR in context.TableOne
from M in context.TableTwo.Where(x => x.ProductID == RR.OrderedProductId || x.ProductID == RR.SoldProductId)
where statusIds.Any(x => x.Equals(RR.StatusID.Value))
select RR.OrderId).ToArray();
Multiple Joins :
var query = (from RR in context.TableOne
join M in context.TableTwo on new { oId = RR.OrderedProductId, sId = RR.SoldProductId} equals new { oId = M.ProductID, sId = M.ProductID }
where RR.CustomerID == CustomerID
&& statusIds.Any(x => x.Equals(RR.StatusID.Value))
select RR.OrderId).ToArray();

Categories

Resources