Linq to Entity Join table with multiple OR conditions - c#

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

Related

Linq Queries - How to join the below two group by queries? On Course ID

I'm trying to join two group by queries to get one results set.
var query = from PP in _db.paymentPlans
join APP in _db.Applications on PP.applicationID equals APP.ApplicationId
join C in _db.Courses on APP.courseID equals C.courseID
where PP.active == true && APP.agentID == agentID
orderby C.courseID ascending
group new {C,PP} by new {C.courseID} into totalRecievable
// Query 1
from PD in _db.paymentDetails
join PP in _db.paymentPlans on PD.paymentPlanID equals PP.paymentPlanID
join APP in _db.Applications on PP.applicationID equals APP.ApplicationId
join C in _db.Courses on APP.courseID equals C.courseID
where PP.active == true && APP.agentID == agentID
orderby C.courseID ascending
group new { C,PD } by new { C.courseID, C.cricosCode, C.courseName } into paymentsCourseWise
// Query 2
select new PdPpAppCourseModel
{
courseID = paymentsCourseWise.Key.courseID,
cricosCode = paymentsCourseWise.Key.cricosCode,
courseName = paymentsCourseWise.Key.courseName,
totalAmount = totalRecievable.Sum(x => x.PP.totalAmount),
paidAmount = paymentsCourseWise.Sum(x => x.PD.paidAmount)
}).ToList();
Total about is taken from query 1 as it should group in payment plan(PP) level.
You can only combine enumerations of the same type, you could project both to a common class and then concatenate them:
var result1 = db1.table.Where(a=>a.value>0).Select( x=> new Foo() { //set props });
var result2 = db2.table.Where(a=>a.value>0).Select( x=> new Foo() { //set props });
var resultSum = result1.Concat(result2);
Similarly you can apply this in your code and join this two groups.

Error in Linq query when join multiple table

My linq query is:
var query1 = (from grp in ctnx.tblGroupDatas
group grp by grp.MeterID_FK into g
let maxId = g.Max(gId => gId.GroupDataID)
select new { metId = g.Key, maxId });
query2 = (from met in ctnx.tblMet
from mod in ctnx.tblMod.Where(mo => mo.ModID == met.Mod_FK).DefaultIfEmpty()
from grp in ctnx.tblGroupDatas.Where(gr => gr.Met_FK == met.MetID)
from group1 in db.tblMetRelateGroups.Where(x => x.Met_FK == met.MetID)
from q1 in query1.Where(q => q.metId == met.MetID && grp.GroupDataID == q.maxId)
where (group1.GroupMetID_FK == groupID)
select new
{
met.MetID,
mod.ModSerial,
met.MetSerial,
met.MetWaterSharingNo,
met.MetPowerSharingNo,
grp.GroupDate,
grp.GroupDataID
});
var gridobisdata = query2.OrderByDescending(m => m.GroupDate);
but this show error:
The specified LINQ expression contains references to queries that are
associated with different contexts.

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 JOIN and OUTER JOIN - How to turn SQL into LINQ expression

I would like to turn the following SQL query into a LINQ expression (using Entity Framework 6.1). Thus far I have been unable find an acceptable LINQ expression that produces similar results. Any help turning this simple SQL statement into a LINQ express would be appreciated.
SELECT AAG.Id AS GroupId,
A.Id AS ActivityId,
A.Title As Title,
CASE WHEN AA.CompletedOn IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS Completed,
COALESCE(AAG.PointValue, 0) + SUM(COALESCE(AQ.PointValue, 0)) AS PointTotal
FROM ActivityAssignmentGroup AAG
INNER JOIN ActivityAssignment AA ON AA.GroupId = AAG.Id
INNER JOIN Activity A ON AA.ActivityId = A.Id
LEFT OUTER JOIN ActivityQuestion AQ ON AQ.ActivityId = A.Id
WHERE AAG.AssignedToId = 6
GROUP BY AAG.Id, A.Id, A.Title, CASE WHEN AA.CompletedOn IS NULL THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END, COALESCE(AAG.PointValue,0)
Without the LEFT OUTER JOIN portion, the below LINQ statement is partially complete, but I cannot figure out the appropriate syntax to add the LEFT OUTER JOIN condition:
var assignments = await (from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId)
join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId
join a in db.Activities.AsNoTracking() on aa.ActivityId equals a.Id
select new ActivityListViewModel
{
Id = a.Id,
Points = g.PointValue ?? 0,
Title = a.Title,
GroupId = g.Id,
Complete = (aa.CompletedOn != null)
});
Edit:
Thanks for the response Bob. I attempted to use the DefaultIfEmpty and looked at the resultant SQL query generated by the Entity Framework, but it didn't work. Prior to making this post, this is the LINQ statement I attempted:
var assignments = from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId)
join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId
join a in db.Activities.AsNoTracking() on aa.ActivityId equals a.Id
from aq in db.ActivityQuestions.Where(q => q.ActivityId == a.Id).DefaultIfEmpty()
group aq by new { ActivityId = aq.ActivityId, Title = a.Title, GroupId = g.Id, Points = g.PointValue ?? 0, Completed = (aa.CompletedOn != null) } into s
select new ActivityListViewModel
{
Id = s.Key.ActivityId,
Points = s.Key.Points + s.Sum(y => y.PointValue ?? 0), //g.PointValue ?? 0,
Title = s.Key.Title,
GroupId = s.Key.GroupId,
Complete = s.Key.Completed
};
Of course, it didn't work either. The result was items missing the Id (ActivityId).
You need DefaultIfEmpty() to convert a join to left outer join, documentition from MSDN here
var assignments = await (from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId)
join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId
join a1 in db.Activities.AsNoTracking() on aa.ActivityId equals a1.Id into a2
from a in a2.DefaultIfEmpty()
select new ActivityListViewModel
{
Id = a == null ? null : a.Id,
Points = g.PointValue ?? 0,
Title = a == null ? null : a.Title,
GroupId = g.Id,
Complete = (aa.CompletedOn != null)
});
Just to close the loop (and thank you Bob Vale)... the query below works:
var assignments = from g in db.AssignmentGroups.AsNoTracking().Where(x => x.AssignedToId == studentTask.Result.PersonId)
join aa in db.ActivityAssignments.AsNoTracking() on g.Id equals aa.GroupId
join a in db.Activities.AsNoTracking() on aa.ActivityId equals a.Id
from aq in db.ActivityQuestions.Where(q => q.ActivityId == a.Id).DefaultIfEmpty()
group aq by new { ActivityId = a.Id, Title = a.Title, GroupId = g.Id, Points = g.PointValue ?? 0, Completed = (aa.CompletedOn != null) } into s
select new ActivityListViewModel
{
Id = s.Key.ActivityId,
Points = s.Key.Points + s.Sum(y => y.PointValue ?? 0), //g.PointValue ?? 0,
Title = s.Key.Title,
GroupId = s.Key.GroupId,
Complete = s.Key.Completed
};
The issue was the group by condition and using ag.ActivityId when I should have used a.Id.

LINQ to SQL in and not in

What is in and not in equals in LINQ to SQL?
For example
select * from table in ( ...)
and
select * from table not in (..)
What is equal to the above statement in LINQ to SQL?
You use, where <list>.Contains( <item> )
var myProducts = from p in db.Products
where productList.Contains(p.ProductID)
select p;
Or you can have a list predefined as such:
int[] ids = {1, 2, 3};
var query = from item in context.items
where ids.Contains( item.id )
select item;
For the 'NOT' case, just add the '!' operator before the 'Contains' statement.
I'm confused by your question. in and not in operate on fields in the query, yet you're not specifying a field in your example query. So it should be something like:
select * from table where fieldname in ('val1', 'val2')
or
select * from table where fieldname not in (1, 2)
The equivalent of those queries in LINQ to SQL would be something like this:
List<string> validValues = new List<string>() { "val1", "val2"};
var qry = from item in dataContext.TableName
where validValues.Contains(item.FieldName)
select item;
and this:
List<int> validValues = new List<int>() { 1, 2};
var qry = from item in dataContext.TableName
where !validValues.Contains(item.FieldName)
select item;
Please Try This For SQL Not IN
var v = from cs in context.Sal_Customer
join sag in context.Sal_SalesAgreement
on cs.CustomerCode equals sag.CustomerCode
where
!(
from cus in context.Sal_Customer
join
cfc in context.Sal_CollectionFromCustomers
on cus.CustomerCode equals cfc.CustomerCode
where cus.UnitCode == locationCode &&
cus.Status == Helper.Active &&
cfc.CollectionType == Helper.CollectionTypeDRF
select cus.CustomerCode
).Contains(cs.CustomerCode) &&
cs.UnitCode == locationCode &&
cs.Status == customerStatus &&
SqlFunctions.DateDiff("Month", sag.AgreementDate, drfaDate) < 36
select new CustomerDisasterRecoveryDetails
{
CustomerCode = cs.CustomerCode,
CustomerName = cs.CustomerName,
AgreementDate = sag.AgreementDate,
AgreementDuration = SqlFunctions.DateDiff("Month", sag.AgreementDate, drfaDate)
};
Please Try This For SQL IN
context.Sal_PackageOrItemCapacity.Where(c => c.ProjectCode == projectCode && c.Status == Helper.Active && c.CapacityFor.Contains(isForItemOrPackage)).ToList();

Categories

Resources