Right outer join in linq-to-sql - c#

I'm new in LINQ , i have query which i wrote with SQL server and i wanna Translate/convert to LINQ.Can anyone direct me in the right direction? thx
This is my SQL:
SELECT Contact.Name, Contact.E-Mail,
Contact Business Relation.No_
FROM Contact Business Relation RIGHT OUTER JOIN
Contact ON Contact Business Relation.Contact No_ = Contact.Company No_
WHERE (Contact.E-Mail = #mail)
This is my LINQ (I'm not sure i did it in right way):
var query = from cbr in db.Contact_Business_Relation
join c in db.Contact
on cbr.Contact_No_ equals c.Company_No_ into f
from c in f.DefaultIfEmpty()
where c.E_Mail == Mail
select new
{
Mail = c.E_Mail,
No = cbr.No_
};

Unfortunately there are no right joins in linq. However, you can rearrange your query to use a left join instead.
var query = from c in db.Contact
join cbr in db.Contact_Business_Relation
on c.Company_No_ equals cbr.Contact_No_ into f
from cbr in f.DefaultIfEmpty()
where c.E_Mail == Mail
select new
{
Mail = c.E_Mail,
No = cbr.No_
};
Join Clause

Related

Making 1 table join on 2 other tables with LINQ

I'm trying to join 1 table onto 2 other tables with LINQ, but I can't seem to figure out how this is done.
I can make it work writing pure SQL statements within Visual studio, I'm just not sure how to convert this into LINQ.
Here's my SQL statement:
SELECT c.CustomerId, c.CustomerName, pw.Number, pc.Number FROM Customers as c
LEFT JOIN Tasks as k ON k.Id = c.Task_Id
LEFT JOIN Workers as w ON w.Id = k.Worker_Id
LEFT JOIN PersonNumbers as pw ON pw.Person_Id = w.Id
LEFT JOIN Chiefs as ch ON ch.Id = k.Chief_Id
LEFT JOIN PersonNumbers as pc ON pc.Person_Id = ch.Id
Perhaps this requires a bit of explanation.
We have a bunch of Customers and these customers can have some tasks. Within a task you will have workers and chiefs. Within the PersonNumbers table, I have some extra information about workers and chiefs, and this is the information that I need.
You should be able to do something like the following assuming all your joins are based on foreign keys that should result in navigation properties in your entities. The DefaultIfEmpty is what makes everything a left join.
var results = from c in db.Customers
from k in c.Tasks.DefaultIfEmpty()
from w in k.Workers.DefaultIfEmpty()
from pw in w.Persons.DefaultIfEmpty()
from ch in k.Chiefs.DefaultIfEmpty()
from pc in ch.Persons.DefaultIfEmpty()
select new
{
c.CustomerId,
c.CustomerName,
pw.Number,
pc.Number
};
If you don't have the navigation properties then you'll have to use join.
var results = from c in db.Customers
join xk in db.Tasks on xk.Id equals c.Task_Id
from k in xk.DefaultIfEmpty()
join xw in db.Workers on xw.Id equals k.Worker_Id
from w in xw.DefaultIfEmpty()
join xpw in db.Persons on xpw.Person_Id equals w.Id
from pw in xpw.DefaultIfEmpty()
join xch in db.Chiefs on xch.Id equals k.Chief_Id
from ch in xch.DefaultIfEmpty()
join xpc in db.Persons on xpc.Person_Id euals ch.Id
from pc in xpc.DefaultIfEmpty()
select new
{
c.CustomerId,
c.CustomerName,
pw.Number,
pc.Number
};

left join failing in query with multiple joins

Before this gets called a duplicate, I have looked around on SO and found a way to do this but it isn't working.
My query is
var GetAllProjects = from f in dc.vw_gmi_all_projects
join mc in dc.gmi_maintenance_classes on f.maintenance_classID equals mc.maintenance_classID
join ms in dc.gmi_maintenance_subclasses on f.maintenance_subclassID equals ms.maintenance_subclassID
join pm in dc.master_project_milestones on f.pmID equals pm.pmID
join ac in dc.vw_master_Countries on f.country_display_name equals ac.country_display_name
join pd in dc.gmi_project_details on f.project_dataID equals pd.project_dataID
join md in dc.vw2_master_districts on f.country_display_name equals md.element_display_name
join ml in dc.vw2_master_lmus on pd.dataID equals ml.elementID into gl from sub in gl.DefaultIfEmpty()
where (mc.maintenance_classID == 3 && ms.maintenance_subclassID != 11)
select new
{
f.project_dataID,
f.projectID,
f.project_title,
f.local_projectID,
f.pm_display_name,
f.reu_name,
f.reuID,
f.sectorID,
f.sector_display_name,
f.country_display_name,
f.maintenance_classID,
f.maintenance_subclassID,
mc.maintenance_class_display_name,
ms.maintenance_subclass_display_name,
pm.pm_name,
ac.region_display_name,
pd.dataID,
md.element_display_name,
ac.cluster_display_name,
display_name = sub.element_display_name
};
foreach (var a in GetAllProjects)
{
lst.Add(new ReportFilter
{
project_dataID = (int)a.project_dataID,
projectID = a.projectID,
project_title = a.project_title,
local_projectID = a.local_projectID,
pm_display_name = a.pm_display_name,
reu_name = a.reu_name,
reuID = a.reuID,
country_display_name = a.country_display_name,
sectorID = a.sectorID,
sector_display_name = a.sector_display_name,
maintenance_classID = a.maintenance_classID,
maintenance_subclassID = a.maintenance_subclassID,
maintenance_class_display_name = a.maintenance_class_display_name,
maintenance_subclass_display = a.maintenance_subclass_display_name,
pm_name = a.pm_name,
region_display_name = a.region_display_name,
dataID = a.dataID,
district = a.element_display_name,
cluster_display_name = a.cluster_display_name
});
}
This is where the left join is supposed to take place..
join ml in dc.vw2_master_lmus on pd.dataID equals ml.elementID into gl from sub in gl.DefaultIfEmpty()
This query runs fine if I leave out the attempt at left join and leave that join out entirely, but I need to get the left join to work so I can get the rest of the records. A typical join won't work like the others because it doesn't return any records.
So where am I going wrong with my query, or doing wrong? I know where its going wrong just not sure how to fix it.
Thanks
More Details
This query creates a list and then I query against this list. However, this query won't return any records because of my attempt at creating a left join.
EDIT
Here is the SQL that I wrote and trying to recreate it using Linq
select * from [vw_gmi_all_projects] f
inner join [gmi_maintenance_classes] mc on f.maintenance_classID = mc.maintenance_classID
inner join [gmi_maintenance_subclasses] ms on f.maintenance_subclassID = ms.maintenance_subclassID
inner join [master_project_milestones] pm on f.pmID = pm.pmID
inner join [vw_master_Countries] ac on f.country_display_name = ac.country_display_name
inner join [gmi_project_details] pd on f.project_dataID = pd.project_dataID
inner join [vw2_master_district] md on f.country_display_name = md.element_display_name
left join [vw2_master_lmu] ml on pd.dataID = ml.elementID
where (mc.maintenance_classID = 3 and ms.maintenance_subclassID != 11)
I hope this helps.
Try the syntax from this answer instead: https://stackoverflow.com/a/4739738/1869660
I think that's an easier syntax when creating LEFT JOINs (note: from, not join).
var GetAllProjects = from f in dc.vw_gmi_all_projects
join mc in dc...
join ms in dc...
join pm in dc...
join ac in dc...
join pd in dc...
join md in dc...
from ml in dc.vw2_master_lmus.Where(ml => ml.elementID == pd.dataID).DefaultIfEmpty()
where ...

translate postgres sql to linq. Is it possible?

I need translate next sql to linq is it possible? That will have approximately the same speed
SELECT Count(tblcollectionimage.lngimageid),
tblcollectiontree.lngcollectionid,
tblcollection.txtname
FROM (tblcollectiontree
LEFT JOIN tblcollectionimage
ON blcollectiontree.lngcollectionid =
tblcollectionimage.lngcollectionid)
JOIN tblcollection
ON tblcollectiontree.lngcollectionid = tblcollection.lngcollectionid
WHERE lngcollectionparentid = 0
GROUP BY tblcollectiontree.lngcollectionid,
tblcollection.txtname
I have currently such linq but it doesn't work.
var results =(from collection in dataBase.tblcollections
join collectionTree in dataBase.tblcollectiontrees on
collection.lngcollectionid equals collectionTree.lngcollectionid
into generalCollections
from generalCollection in generalCollections
join images in dataBase.tblcollectionimages on
collection.lngcollectionid equals images.lngcollectionid
into generalCollectionImages
from generalCollectionImage in
generalCollectionImages.DefaultIfEmpty()
group generalCollectionImage by
generalCollectionImage.lngcollectionid into hello
from hellos in hello.DefaultIfEmpty()
join collection in dataBase.tblcollections on
hello.Key equals collection.lngcollectionid
select new
{
id = hello.Key,
name = hello.Count()
}).ToList();

LEFT LINQ TO SQL C# JOIN on many to many table

Hi im kinda new to linq to sql I know about the basics. The problem is I want to do a left join in a query. There are 3 tables in the query.
Claimants ( all rows should be returned from this table)
Claim
User
The query should return all Users who have Claimants. This is done through the many to many table Claim. But regardless of Users all Claimants should be returned. Thus the left join on Claimants.
I have the following query
var d = (from Claimants in DB.Claimants
join Claims in DB.Claims on Claimants.Claiment_ID equals Claims.Claiment_ID
join Users in DB.Users on Claims.User_ID equals Users.User_ID
where (Claimants.TrialDate.Value >= dtDayStart & Claimants.TrialDate <= dtDayEnd)
select new
{
ClaimantFirstName = Claimants.FirstName,
ClaimantLasname = Claimants.LastName,
ClaimantsID = Claimants.IDNumber,
Claimants.OurReference,
Claimants.TrialDate,
InterviewStart = Claims.DateTimeStart,
InterviewEnd = Claims.DateTimeEnd,
Claims.Priority,
UserFirstname = Users.FirstName,
UserLastName = Users.LastName,
UserID = Users.IDNumber
});
I have tried using an into statement as follows but with no luck
var d = (from Claimants in DB.Claimants
join Claims in DB.Claims on Claimants.Claiment_ID equals Claims.Claiment_ID
into TheClaimants
from Claims in TheClaimants.DefaultIfEmpty()
join Users in DB.Users on Claims.User_ID equals Users.User_ID
where (Claimants.TrialDate.Value >= dtDayStart & Claimants.TrialDate <= dtDayEnd)
select new
{
ClaimantFirstName = Claimants.FirstName,
ClaimantLasname = Claimants.LastName,
ClaimantsID = Claimants.IDNumber,
Claimants.OurReference,
Claimants.TrialDate,
InterviewStart = Claims.DateTimeStart,
InterviewEnd = Claims.DateTimeEnd,
Claims.Priority,
UserFirstname = Users.FirstName,
UserLastName = Users.LastName,
UserID = Users.IDNumber
});
I would appreciate it if someone could point me in the right direction as to how to use these joins left right correctly and explain how the work. Thank you very much in advance.
var d = (from Claimants in DB.Claimants
join Claims in DB.Claims on Claimants.Claiment_ID equals Claims.Claiment_ID)
.DefaultIfEmpty()
join Users in DB.Users on Claims.User_ID equals Users.User_ID
where (Claimants.TrialDate.Value >= dtDayStart & Claimants.TrialDate <= dtDayEnd)
.DefaultIfEmpty()
select new
{
ClaimantFirstName = Claimants.FirstName,
ClaimantLasname = Claimants.LastName,
ClaimantsID = Claimants.IDNumber,
Claimants.OurReference,
Claimants.TrialDate,
InterviewStart = Claims.DateTimeStart,
InterviewEnd = Claims.DateTimeEnd,
Claims.Priority,
UserFirstname = Users.FirstName,
UserLastName = Users.LastName,
UserID = Users.IDNumber
});
Left outter join
You must know a Luan. If you want all the Claiments to return start by selecting from Claiments and then left join onto the other tables.
Try the following :
LINQ to SQL Left Outer Join
In LINQ, the ".Join()" extension method is the equivalent of SQL inner join.
For outer joins you have to use the ".GroupJoin()" extension method.
Assuming you know the .Join well, the GroupJoin is simple to use. I have to admit that when I first needed to do an outer join in LINQ it was damn hard to find out. I cannot fanthom why did they call it like that.
Although in VB.Net, here's an article that presents various SQL constructs translated into LINQ syntax, even if in VB, still easy to convert to extension methods: http://blogs.msdn.com/b/vbteam/archive/2007/12/31/converting-sql-to-linq-part-6-joins-bill-horst.aspx?Redirected=true
EDIT: #DavidB posted in his comments a much better solution, but only if you can use some ORM navigational properties. If you don't have them, then GroupJoin is probably the most reasonable

Linq to SQL Joining to the Same Table Twice for Two Different Tables

How do I write this SQL in Linq to SQL using C#. I cannot get the join to the status table to both ConsumerApplications and RepairOrderEstimates to work properly. Thanks.
select ca.ConsumerAppID,
ca.LastName,
statConsumerApp.StatusName,
statRepairOrderEstimates.StatusName
from ConsumerApplications ca
join RepairOrderEstimates
on ca.RepairOrderEstimateID = RepairOrderEstimates.RepairOrderEstimateID
join Statuses statConsumerApp
on ca.StatusID = statConsumerApp.StatusID
join Statuses statRepairOrderEstimates
on RepairOrderEstimates.StatusID = statRepairOrderEstimates.StatusID
I think you can do this with something like
from ca in ConsumerApplications
join est in RepairOrderEstimates on ca.RepairOrderEstimateID == est.RepairOrderEstimateID
join statConsumerApp in Statuses on ca.StatusID == statConsumerApp.StatusID
join statEstimate in Statuses on est.StatusID == statEstimate.StatusID
select new {
ConsumerAppID = ca.ConsumerAppID,
LastName = ca.LastName,
AppStatus = statConsumerApp.StatusName,
EstimateStatus = statEstimate.StatusName,
}

Categories

Resources