Linq Left join query in c# - c#

Doing some stuff linq left join query but facing some problem. Not able to get proper result following sql query need to convert into linq
INSERT INTO tbl_service_order_attributes_versioning(ServiceOrderNo, AttributeId, AttributeValue, parentid, AttributeType, Dt_Stamp, VERSION)
SELECT
T.ServiceOrderNo, T.COIID, T.COI_Identifier,
#pid, 'MBM', getDate(), #ORDERVERSION
FROM
#temp1 T
LEFT JOIN
tbl_service_order_attributes_versioning O WITH(NOLOCK)
ON T.ServiceOrderNo = O.ServiceOrderNo COLLATE database_default
AND T.COIID = O.AttributeID
AND O.PARENTID = #pid
WHERE
O.ServiceOrderNo IS NULL
I have converted this query into a Linq query:
var soiAttr = (from s in ctxParser.TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING
where s.ParentId == parentId
select s).ToList();
var resultJoinCOI = (from soaI in soiAttr
join iFoi in listFOI on soaI.ServiceOrderNo equals iFoi.fulfilmentOrderItemIdentifier
where iFoi.coiId == soaI.AttributeId &&
iFoi.parentId == parentId &&
soaI.ServiceOrderNo == null
select iFoi).ToList();
if (resultJoinCOI.Count > 0)
{
var listToInsert = (from item in resultJoinCOI
select new TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING
{
ServiceOrderNo = item.fulfilmentOrderItemIdentifier,
AttributeId = item.coiId,
AttributeValue = item.coiIdentifier,
ParentId = parentId,
AttributeType = "MBM",
DT_Stamp = DateTime.Now,
VERSION = orderVersion
});
ctxParser.TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING.AddRange(listToInsert);
ctxParser.SaveChanges();
}
The code is executed but result are not correct.

You need to use DefaultIfEmpty (https://msdn.microsoft.com/en-us/library/bb360179.aspx). Here's a reading from MSDN: https://msdn.microsoft.com/en-us/library/bb397895.aspx
In your case it would be something like:
var resultJoinCOI = (
from iFoi in listFOI
join soaI in soiAttr on iFoi.fulfilmentOrderItemIdentifier equals soaI.ServiceOrderNo into res
from subIFoi in res.DefaultIfEmpty()
where iFoi.coiId == soaI.AttributeId && iFoi.parentId == parentId && subIFoi == null
select iFoi).ToList();

Following code that execute successfully. and getting right result.
var soiAttr = (from s in ctxParser.TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING
where s.ParentId == parentId
select s).ToList();
var resultJoinCOI = (from iFoi in listFOI
join soaI in soiAttr on
new
{
ServiceOrderNo = iFoi.fulfilmentOrderItemIdentifier,
AttributeId = iFoi.coiId
}
equals new
{
ServiceOrderNo = soaI.ServiceOrderNo,
AttributeId = soaI.AttributeId
}
into res
from subFoi in res.DefaultIfEmpty()
select new
{
fulfilmentOrderItemIdentifier = iFoi.fulfilmentOrderItemIdentifier,
coiId = iFoi.coiId,
coiIdentifier = iFoi.coiIdentifier,
AttributeId = subFoi == null ? 0 : subFoi.AttributeId,
ParentId = subFoi == null ? parentId : subFoi.ParentId,
ServiceOrderNo = subFoi == null ? string.Empty: subFoi.ServiceOrderNo
});
if (resultJoinCOI != null)
{
if (resultJoinCOI.Count() > 0)
{
var listToInsert = (from item in resultJoinCOI
select new TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING
{
ServiceOrderNo = item.fulfilmentOrderItemIdentifier,
AttributeId = item.coiId,
AttributeValue = item.coiIdentifier,
ParentId = parentId,
AttributeType = "MBM",
DT_Stamp = DateTime.Now,
VERSION = orderVersion
});
ctxParser.TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING.AddRange(listToInsert);
ctxParser.SaveChanges();
}
}
In this way we can implement left join in linq. as per above SQL Query(see above sql statement).

Related

How to apply case when function in Linq

I have a Linq query to fetch data from databse using entity framework. I have to apply the given sql condetion to the linq query.My sample sql query is
DECLARE #EmrId NVARCHAR(50)
set #EmrId='784197621725304'
SELECT
[ftp_imptlg_ImprtTyp_id],[ftp_imptlg_daypath],[ftp_imptlg_subfolderpath]
,[ftp_imptlg_emirates_id],[ftp_imptlg_srcfile_name],[ftp_imptlg_filereadon]
,[ftp_imptlg_opr_status],[ftp_imptlg_doc_no],[ftp_imptlg_emp_id]
,[ftp_imptlg_upld_filename] ,[ftp_imptlg_doctype_id]
FROM [C3KYC].[dbo].[ftp_import_logs] AS c
inner join tm_doc_type as d on c.[ftp_imptlg_doctype_id]=d.doc_typeid
inner join tm_import_type as e on c.[ftp_imptlg_ImprtTyp_id]=e.imprttype_id
WHERE c.ftp_imptlg_emirates_id = case when #EmrId ='0' then
c.ftp_imptlg_emirates_id else #EmrId end
AND
c.ftp_imptlg_opr_status='failed'
and d.doc_typeid=6
and e.imprttype_id='2'
I tried the below linq query
string strEmrid = EmiratesId != null ? EmiratesId : "0";
using (var db = new DB_KYC3Entities())
{
db.Configuration.ProxyCreationEnabled = false;
List<ImportLogDetails> listofLogDetails = (from c in db.ftp_import_logs
join d in db.tm_doc_type on c.ftp_imptlg_doctype_id equals d.doc_typeid
join e in db.tm_import_type on c.ftp_imptlg_ImprtTyp_id equals e.imprttype_id
where c.ftp_imptlg_ImprtTyp_id == ImportTypeId
&& c.ftp_imptlg_emirates_id == strEmrid
&& c.ftp_imptlg_opr_status== "Failed"
&& d.doc_typeid== 6
&& e.imprttype_id== "2"
select new ImportLogDetails
{
ImportType = e.imprtTye_name,
SourcePath = c.ftp_imptlg_subfolderpath,
DateOfAction = c.ftp_imptlg_filereadon,
DocumentType = d.doctype_name,
EmiratesId = c.ftp_imptlg_emirates_id,
Status = c.ftp_imptlg_opr_status,
KycEmployeeId = c.ftp_imptlg_emp_id,
DocumentTypeId = c.ftp_imptlg_doctype_id
}).ToList();
return listofLogDetails;
You can use ?: operator in LINQ,
x.Where( x => x.ftp_imptlg_emirates_id == (
x.ftp_imptlg_emirates_id == "0" ? "0" : x.ftp_imptlg_emirates_id
))
Your query,
string strEmrid = EmiratesId != null ? EmiratesId : "0";
using (var db = new DB_KYC3Entities())
{
db.Configuration.ProxyCreationEnabled = false;
List<ImportLogDetails> listofLogDetails = (from c in db.ftp_import_logs
join d in db.tm_doc_type on c.ftp_imptlg_doctype_id equals d.doc_typeid
join e in db.tm_import_type on c.ftp_imptlg_ImprtTyp_id equals e.imprttype_id
where c.ftp_imptlg_ImprtTyp_id == ImportTypeId
&&
c.ftp_imptlg_emirates_id == (strEmirId == "0" ? c.ftp_imptlg_emirates_id : strEmirid)
&& c.ftp_imptlg_opr_status== "Failed"
&& d.doc_typeid== 6
&& e.imprttype_id== "2"
select new ImportLogDetails
{
ImportType = e.imprtTye_name,
SourcePath = c.ftp_imptlg_subfolderpath,
DateOfAction = c.ftp_imptlg_filereadon,
DocumentType = d.doctype_name,
EmiratesId = c.ftp_imptlg_emirates_id,
Status = c.ftp_imptlg_opr_status,
KycEmployeeId = c.ftp_imptlg_emp_id,
DocumentTypeId = c.ftp_imptlg_doctype_id
}).ToList();
return listofLogDetails;

How to pull one column from second table in Linq query with join

I have the following linq query that works fine, but I am wanting to pull one column (CompanyId) from context.Emps into the results along with the results from context.BillingProfiles. How would I modify the select (select prof) below to include said column?
var query = (from prof in context.BillingProfiles
join emp in context.Emps on prof.ID equals emp.ID
join grp in context.BillingGroups on prof.GroupID equals grp.GroupID
where (prof.EndDate == null) && (grp.System == "sysGrp") && (prof.ID == id)
select prof).Distinct()
.Select(x => new OpId()
{
id = x.ID,
GroupId = x.GroupID,
OpId = x.OpID,
StartDate = x.StartDate,
EndDate = x.EndDate,
AddedOn = x.AddedOn,
AddedBy = x.AddedBy,
RemovedOn = x.RemovedOn,
RemovedBy = x.RemovedBy,
Prodid = x.ProdID,
});
Thanks
Project an anonymous object containing those too:
var query = from prof in context.BillingProfiles
join emp in context.Emps on prof.ID equals emp.ID
join grp in context.BillingGroups on prof.GroupID equals grp.GroupID
where prof.EndDate == null && prof.ID == id && grp.System == "sysGrp"
select new { prof, emp.CompanyId, grp };

SQL to Linq statement

I've got this SQL statement that I'm trying to convert to linq:
SELECT i.*
FROM Issues i
WHERE IssueID IN (SELECT ChildIssueId
FROM LinkedIssues
WHERE IssueId = 28438)
OR IssueID IN (SELECT IssueId
FROM LinkedIssues
WHERE ChildIssueId = 28438)
Here's what the data in the table looks like:
So in the sql above, I get issues 19220, 28436, & 28440 back. Here's what I've tried with no luck:
var childIssues = (from i in Issues
join li in LinkedIssues
on i.IssueID equals li.IssueId
where (from li2 in LinkedIssues
where li.IssueId == 28438 || li.ChildIssueId == 28438
select li2).Contains(28438)
select new LinkedIssuesModel()
{
IssueID = li.ChildIssueId,
CustomerName = i.Room.Location.Customer.CustomerName,
LocationName = i.Room.Location.LocationName,
ReceivedDate = i.ReceivedDate,
IssueSummary = i.IssueSummary,
IssueDescription = i.IssueDescription
}).ToList();
I need to know how to convert SQL IN statements to linq. I have LinqPad but it doesn't convert it when I click the lambda button. I've also downloaded and tried Linqer but it throws an "Object not set to an instance Object" error.
Please try the following:
var childIssues = (from i in Issues
from li in LinkedIssues
where (li.IssueId == 28438 && li.ChildIssueId == i.IssueID)
|| (li.ChildIssueId == 28438 && li.IssueId == i.IssueID)
select new LinkedIssuesModel()
{
IssueID = li.ChildIssueId,
CustomerName = i.Room.Location.Customer.CustomerName,
LocationName = i.Room.Location.LocationName,
ReceivedDate = i.ReceivedDate,
IssueSummary = i.IssueSummary,
IssueDescription = i.IssueDescription
}).ToList();
EDIT: Fixed query to address li.ChildIssueId on the select.
You are not joining.
var childIssues = Issues.
Where(x => LinkedIssues.
Where(z => z.IssueId = 28438).
Select(z => z.ChildIssueId).
Contains(x.IssueID)
||
LinkedIssues.
Where(z => z.ChildIssueId = 28438).
Select(z => z.IssueId).
Contains(x.IssueID)
);

LINQ Left join Query

I am trying converting sql query into LINQ but after write query unable to fetch record from resultset
SELECT T.ServiceOrderNo,T.STATUS, T.SubStatus,T.orderVersion,T.OrderDate
,#pid, T.EventID, 'FOI'
FROM #temp1 T
LEFT JOIN Tbl_Service_Order_Progress O ON T.ServiceOrderNo DATABASE_DEFAULT = O.ServiceOrderNo
AND O.PARENTID = #pid
AND O.ServiceOrderType = 'FOI'
WHERE O.ServiceOrderNo IS NULL
Above Query following I'm trying in LINQ
var lstInsertFOI = (from i in lstFOI
join j in lstSOP on i.fulfilmentOrderItemIdentifier equals j.ServiceOrderNo into res
from subRight in res.DefaultIfEmpty()
where subRight.ParentId == parentId && subRight.ServiceOrderNo == null && subRight.ServiceOrderType.Equals("FOI")
select new
{
ServiceOrderNo = subRight.ServiceOrderNo == null ? i.fulfilmentOrderItemIdentifier : subRight.ServiceOrderNo,
EventStatus = i.status,
EventSubStatus = i.subStatus,
OrderVersion = i.orderVersion,
EVENTRECEIVEDDATE = i.orderDate,
ParentId = parentId,
EventID = i.eventID,
ServiceOrderType = "FOI",
}).ToList();
above linq query does not fetch expected result, which should return number of records from lstFOI list, but returns no record. Is the linq query correct?
Let start with SQL query.
LEFT JOIN Tbl_Service_Order_Progress O
ON T.ServiceOrderNo = O.ServiceOrderNo
AND O.PARENTID = #pid AND O.ServiceOrderType = 'FOI'
is equivalent to
LEFT JOIN (SELECT * FROM Tbl_Service_Order_Progress
WHERE PARENTID = #pid AND ServiceOrderType = 'FOI') O
ON T.ServiceOrderNo = O.ServiceOrderNo
then
WHERE O.ServiceOrderNo IS NULL
means that the query is actually using anti-join, i.e. include all the records from the left side that do not have a matching records from the right side.
With all that in mind, the equivalent LINQ query should be like this:
var lstInsertFOI = (
from i in lstFOI
join j in lstSOP
.Where(e => e.ParentId == parentId && subRight.ServiceOrderType == "FOI")
on i.fulfilmentOrderItemIdentifier equals j.ServiceOrderNo into res
where !res.Any()
select new
{
ServiceOrderNo = i.fulfilmentOrderItemIdentifier,
EventStatus = i.status,
EventSubStatus = i.subStatus,
OrderVersion = i.orderVersion,
EVENTRECEIVEDDATE = i.orderDate,
ParentId = parentId,
EventID = i.eventID,
ServiceOrderType = "FOI",
}).ToList();

Select Values from two tables using Linq

Hi I know this has been asked plenty of times, I'm not getting it through my skull
How to select Values from several tables
I made these two Linq queries
First
r = (from d in db.stageManagers
where d.profileID == UserID && d.verticalID == VerticalID
select new StageModels()
{
UserId = d.profileID,
VerticalId = (int)d.verticalID,
VerticalStageID = d.stageID
}).FirstOrDefault();
Second
r = (from d in db.stageManagerVerticals
where d.ID == r.VerticalId
select new StageModels()
{
VerticalName = d.verticalName
}
).FirstOrDefault();
I want to make them one statement since they add data to one model and the tables they query have a Pk Fk relationship
In the first block d.verticalId is what I use to get the value(Name) in the secondblock, d.verticalId is primary key to stageManagerVerticals and foreign key in stageManager, How can i join these queries ?
I tried this:
r = (from d in db.stageManagers
join c in db.stageManagerVerticals on d.stageID equals c.ID
where d.profileID == UserID && d.verticalID == VerticalID
select new StageModels()
{
UserId = d.profileID,
VerticalId = (int)d.verticalID,
VerticalStageID = d.stageID;
VerticalName = c.verticalName
}
).FirstOrDefault();
try with JOIN in LINQ to select values from more than one table
eg:
var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { ProductName = prod.Name, Category = category.Name };
var leftOuterJoin=(c in categories
join p in products on c.ID equals p.CategoryID into t
from temp in t.DefaultIfEmpty()
select new { ProductName = p.Name, Category = c.Name }
).ToList();
You can utilize the Navigational Properties,
var r = db.stageManagers.Where(x => x.profileID == UserID && x.verticalID == VerticalID).
Select(
d => new StageModels() {
UserID = d.profileID,
VerticalID = (int)d.verticalID,
VerticalStageID = d.stageID,
VerticalName = d.stageManagerVertical.verticalName
}
).FirstOrDefault();

Categories

Resources