entity framework - inner join to left join - c#

Good day! I need transform join to left join in my query -
var query = (from sections in context.Sections
join themes in context.Themes on sections.SectionId equals themes.SectionId
join comments in context.Comments on themes.ThemeId equals comments.ThemeId
select new { sections.SectionId, sections.SectionTitle, themes.ThemeId, comments.CommentId } into x
group x by new { x.SectionId, x.SectionTitle } into g
select new SectionInfo
{
SectionId = g.Key.SectionId,
SectionTitle = g.Key.SectionTitle,
ThemeCount = g.Select(s => s.ThemeId).Count(),
CommentCount = g.Select(s => s.CommentId).Count()
}).ToList();
- please, i have no idea(

You need to use DefaultIfEmpty
One way is like this:
from themes in context.Themes.Where(x => sections.SectionId == x.SectionId)
.DefaultIfEmpty()
Alternate way
join themes in context.Themes on sections.SectionId equals themes.SectionId into themesGroup
from themes in themesGroup.DefaultIfEmpty()

Related

Adding Count Column to LINQ query Based on Joined Table

So I have a SQL view that I've created that provides me what I need. Essentially it's a job position billeting system that shows how many positions have been authorized vs filled (or assigned).
SELECT Companies.Name AS Company, Grades.Name AS Grade, Series.Name
AS Series, Positions.Authorized, COUNT(People.PersonId) AS Assigned
FROM Companies INNER JOIN
Positions ON Companies.Id = Positions.CompanyId INNER JOIN
Series ON Positions.SeriesId = Series.Id INNER JOIN
Grades ON Positions.GradeId = Grades.Id INNER JOIN
People ON Positions.CompanyId = People.CompanyId AND
Positions.SeriesId = People.SeriesId AND Positions.GradeId = People.GradeId
GROUP BY Companies.Name, Grades.Name, Series.Name, Positions.Authorized
Now what I'd like to be able to do is recreate this in a LINQ query. I've almost got it where I need it; however, I can't figure out how to add the counted column at the end that's based on the People table.
Here's my current LINQ query:
var query = from a in db.Companies
join b in db.Positions on a.Id equals b.CompanyId
join c in db.Series on b.SeriesId equals c.Id
join d in db.Grades on b.GradeId equals d.Id
join e in db.People on new { b.CompanyId, b.SeriesId, b.GradeId } equals new { e.CompanyId, e.SeriesId, e.GradeId }
group a by new { CompanyName = a.Name, GradeName = d.Name, SeriesName = c.Name, b.Authorized, e.PersonId } into f
select new { Company = f.Key.CompanyName, Grade = f.Key.GradeName, Series = f.Key.SeriesName, f.Key.Authorized, Assigned = /* needs to be Count(People.PersonId) based on last join */ )};
Thanks in advance for any help you can provide!
Figured it out. The reason why it was posting multiple rows and not doing a proper count on the same row was because in my "group by" I added in "e.PersonId" when it should have simply been removed. I also had to add a few things to make it work on the front-end razor views since it's an anonymous type (this doesn't have anything to do with the original question, but thought I'd give reason to the changes). So the person who removed their answer, you were partially right, but the reason it wasn't working was because of the additional fieldin the group by:
dynamic query = (from a in db.Companies
join b in db.Positions on a.Id equals b.CompanyId
join c in db.Series on b.SeriesId equals c.Id
join d in db.Grades on b.GradeId equals d.Id
join e in db.People on new { b.CompanyId, b.SeriesId, b.GradeId } equals new { e.CompanyId, e.SeriesId, e.GradeId }
group a by new { CompanyName = a.Name, GradeName = d.Name, SeriesName = c.Name, b.Authorized } into f
select new { Company = f.Key.CompanyName, Grade = f.Key.GradeName, Series = f.Key.SeriesName, Authorized = f.Key.Authorized, Assigned = f.Count()}).AsEnumerable().Select(r => r.ToExpando());
And what it looks like on the page:

How to join 3 tables with linq

I am trying to join 3 tables in a query with Linq to get data from all 3 tables. Below is an image of the table schemes:
The query should select: SewagePlantName, CompanyName and Duty
In addition I need to restricts the SewagePlantId to a list of Ids that are given as:
var sewagePlantIds = UnitOfWork.GetAll<UserGroup>()
.Where(group => group.Id == webAppPrincipal.GroupId)
.SelectMany(group => group.SewagePlantId).Select(sewageplant => sewageplant.Id).ToList();
I have difficulties with the order of joining the 3 tables and where/how to restrict the SewagePlantId to the given list.
Can you try something similar to it please for joining part
from d in Duty
join c in Company on d.CompanyId equals c.id
join s in SewagePlant on c.SewagePlantId equals s.id
select new
{
duty = s.Duty.Duty,
CatId = s.Company.CompanyName,
SewagePlantName=s.SewagePlant.SewagePlantName
// other assignments
};
var obj = from trns in context.tblPartyRegistrations
join st in context.tblSellingTrans
on trns.PartyRegId equals st.Fk_PartyRegId
join pt in context.tblPartyRemainings
on trns.PartyRegId equals pt.fk_PartyId
select new
{
trns.Name,
trns.PhoneNo,
trns.Address,
st.RecivedAmount,
st.Date,
st.CustomerType,
st.MilkRate,
st.Mltr,
st.Mkg,
st.NtAmnt,
st.RemaningAmount,
pt.Remainingammount
};

How can I use my class properties in my Linq query with group by statement?

I would like to use my entity class properties in my linq query that return some value with it.
so this my linq query;
List<PvmBarChartData> BaseofSegmentIPPGMR = (from si in db.ScoreItem
join s in db.Score on si.ScoreId equals s.Id
join prg in db.ProjectResearchGroup on si.ProjectResearchGroupId equals prg.Id
join rg in db.RgClone on prg.RgCloneId equals rg.Id
join sp in db.SalesPoint on s.SalesPointId equals sp.Id
join c in db.Channel on sp.ChannelId equals c.Id
where (si.ResearchGroupType == ResearchGroupType.ScoreCard && spIds.Contains(s.SalesPointId))
group si by c.Name into g
select new PvmBarChartData
{
GroupName = g.Key,
DataValues = new List<CvmNameValuePair>{ new CvmNameValuePair{
Name = "",
Value = g.Average(x => x.TotalScore)
}
}
})
.ToList();
so for instance I would like to set Name properties with my entity framework model class' properties' value, Name = s.Name,
How can I implement this on my code?
A way that you can access s.Name is by doing another linq query on g, since g is now a data set of grouped objects.
Name = (from gx in g select gx.Name).FirstorDefault();

SQL query to linq with right and left joins and nested query

My sql query is
SELECT DISTINCT
tblProjects.RevID, tblProjects.CEQRNum, tblProjects.ProjectName, GEOCODE.BBL, tblProjects.BoroID, GEOCODE.BLOCK, GEOCODE.LOT,
tblMilestoneType.MilestoneName, tblMilestone.MilestoneDate
FROM tblMilestoneType INNER JOIN
tblMilestone ON tblMilestoneType.MilestoneID = tblMilestone.MilestoneTypeID RIGHT OUTER JOIN
tblProjects ON tblMilestone.RevID = tblProjects.RevID LEFT OUTER JOIN
GEOCODE ON tblProjects.RevID = GEOCODE.RevID
WHERE (
tblMilestone.MilestoneDate IN (SELECT MAX(tblMilestone.MilestoneDate) AS MilestoneDate
FROM tblMilestone INNER JOIN tblMilestoneType ON tblMilestone.MilestoneTypeID = tblMilestoneType.MilestoneID
GROUP BY tblMilestone.RevID)
)
ORDER BY tblProjects.RevID
I am trying to convert this to linq.
So i started with
projectList = db.tblMilestoneTypes
.Join(db.tblMilestones,
mileType => mileType.MilestoneID,
mile => mile.MilestoneTypeID,
(mileType, mile) => new
{
tblMilestoneType = mileType,
tblMilestone = mile
})
.Join(db.tblProjects,
project => project. // does not work)
Also tried
projectList = from MilestoneTypeTable in db.tblMilestoneTypes
join MilestoneTable in db.tblMilestones on MilestoneTypeTable.MilestoneID equals MilestoneTable.MilestoneTypeID
rig // no right or left join.
How do i do this
Neha
You can try
projectList = from MilestoneTypeTable in db.tblMilestoneTypes
join MilestoneTable in db.tblMilestones on MilestoneTypeTable.MilestoneID equals MilestoneTable.MilestoneTypeID into MileStones
from mileStone in MileStones
join from projects in db.tblProjects
on mileStone.RevID equals projects.RevID
select new { MileStoneType = MilestoneTypeTable, MileStones = mileStone , Project = projects };
Well After a lot of R&D This is what I found out
the T-SQL with LEFT OUTER JOIN and RIGHT OUTER JOIN can be converted to one query with only LEFT OUTER JOIN
put subquery as a part of join
and here is the query.
var query = from ProjectTable in db.tblProjects
from GeoCodeTable in db.GEOCODEs.Where(geo => geo.RevID == ProjectTable.RevID).DefaultIfEmpty()
from MilestoneTable in db.tblMilestones.Where(mile => mile.RevID == GeoCodeTable.RevID && mile.MilestoneDate == db.tblMilestones.OrderBy(x => x.RevID).Select(x => x.MilestoneDate).Max()).DefaultIfEmpty()
from MilestomeTypeTable in db.tblMilestoneTypes.Where(mt => mt.MilestoneID == MilestoneTable.MilestoneTypeID).DefaultIfEmpty()
select new
{
Milestone = MilestoneTable,
Project = ProjectTable,
GeoCode = GeoCodeTable,
MilestomeType = MilestomeTypeTable
};

What is the syntax for an inner join in LINQ to SQL?

I'm writing a LINQ to SQL statement, and I'm after the standard syntax for a normal inner join with an ON clause in C#.
How do you represent the following in LINQ to SQL:
select DealerContact.*
from Dealer
inner join DealerContact on Dealer.DealerID = DealerContact.DealerID
It goes something like:
from t1 in db.Table1
join t2 in db.Table2 on t1.field equals t2.field
select new { t1.field2, t2.field3}
It would be nice to have sensible names and fields for your tables for a better example. :)
Update
I think for your query this might be more appropriate:
var dealercontacts = from contact in DealerContact
join dealer in Dealer on contact.DealerId equals dealer.ID
select contact;
Since you are looking for the contacts, not the dealers.
And because I prefer the expression chain syntax, here is how you do it with that:
var dealerContracts = DealerContact.Join(Dealer,
contact => contact.DealerId,
dealer => dealer.DealerId,
(contact, dealer) => contact);
To extend the expression chain syntax answer by Clever Human:
If you wanted to do things (like filter or select) on fields from both tables being joined together -- instead on just one of those two tables -- you could create a new object in the lambda expression of the final parameter to the Join method incorporating both of those tables, for example:
var dealerInfo = DealerContact.Join(Dealer,
dc => dc.DealerId,
d => d.DealerId,
(dc, d) => new { DealerContact = dc, Dealer = d })
.Where(dc_d => dc_d.Dealer.FirstName == "Glenn"
&& dc_d.DealerContact.City == "Chicago")
.Select(dc_d => new {
dc_d.Dealer.DealerID,
dc_d.Dealer.FirstName,
dc_d.Dealer.LastName,
dc_d.DealerContact.City,
dc_d.DealerContact.State });
The interesting part is the lambda expression in line 4 of that example:
(dc, d) => new { DealerContact = dc, Dealer = d }
...where we construct a new anonymous-type object which has as properties the DealerContact and Dealer records, along with all of their fields.
We can then use fields from those records as we filter and select the results, as demonstrated by the remainder of the example, which uses dc_d as a name for the anonymous object we built which has both the DealerContact and Dealer records as its properties.
var results = from c in db.Companies
join cn in db.Countries on c.CountryID equals cn.ID
join ct in db.Cities on c.CityID equals ct.ID
join sect in db.Sectors on c.SectorID equals sect.ID
where (c.CountryID == cn.ID) && (c.CityID == ct.ID) && (c.SectorID == company.SectorID) && (company.SectorID == sect.ID)
select new { country = cn.Name, city = ct.Name, c.ID, c.Name, c.Address1, c.Address2, c.Address3, c.CountryID, c.CityID, c.Region, c.PostCode, c.Telephone, c.Website, c.SectorID, Status = (ContactStatus)c.StatusID, sector = sect.Name };
return results.ToList();
You create a foreign key, and LINQ-to-SQL creates navigation properties for you. Each Dealer will then have a collection of DealerContacts which you can select, filter, and manipulate.
from contact in dealer.DealerContacts select contact
or
context.Dealers.Select(d => d.DealerContacts)
If you're not using navigation properties, you're missing out one of the main benefits on LINQ-to-SQL - the part that maps the object graph.
Use Linq Join operator:
var q = from d in Dealer
join dc in DealerConact on d.DealerID equals dc.DealerID
select dc;
basically LINQ join operator provides no benefit for SQL. I.e. the following query
var r = from dealer in db.Dealers
from contact in db.DealerContact
where dealer.DealerID == contact.DealerID
select dealerContact;
will result in INNER JOIN in SQL
join is useful for IEnumerable<> because it is more efficient:
from contact in db.DealerContact
clause would be re-executed for every dealer
But for IQueryable<> it is not the case. Also join is less flexible.
Actually, often it is better not to join, in linq that is. When there are navigation properties a very succinct way to write your linq statement is:
from dealer in db.Dealers
from contact in dealer.DealerContacts
select new { whatever you need from dealer or contact }
It translates to a where clause:
SELECT <columns>
FROM Dealer, DealerContact
WHERE Dealer.DealerID = DealerContact.DealerID
Inner join two tables in linq C#
var result = from q1 in table1
join q2 in table2
on q1.Customer_Id equals q2.Customer_Id
select new { q1.Name, q1.Mobile, q2.Purchase, q2.Dates }
Use LINQ joins to perform Inner Join.
var employeeInfo = from emp in db.Employees
join dept in db.Departments
on emp.Eid equals dept.Eid
select new
{
emp.Ename,
dept.Dname,
emp.Elocation
};
Try this :
var data =(from t1 in dataContext.Table1 join
t2 in dataContext.Table2 on
t1.field equals t2.field
orderby t1.Id select t1).ToList();
OperationDataContext odDataContext = new OperationDataContext();
var studentInfo = from student in odDataContext.STUDENTs
join course in odDataContext.COURSEs
on student.course_id equals course.course_id
select new { student.student_name, student.student_city, course.course_name, course.course_desc };
Where student and course tables have primary key and foreign key relationship
try instead this,
var dealer = from d in Dealer
join dc in DealerContact on d.DealerID equals dc.DealerID
select d;
var Data= (from dealer in Dealer join dealercontact in DealerContact on dealer.ID equals dealercontact.DealerID
select new{
dealer.Id,
dealercontact.ContactName
}).ToList();
var data=(from t in db.your tableName(t1)
join s in db.yourothertablename(t2) on t1.fieldname equals t2.feldname
(where condtion)).tolist();
var list = (from u in db.Users join c in db.Customers on u.CustomerId equals c.CustomerId where u.Username == username
select new {u.UserId, u.CustomerId, u.ClientId, u.RoleId, u.Username, u.Email, u.Password, u.Salt, u.Hint1, u.Hint2, u.Hint3, u.Locked, u.Active,c.ProfilePic}).First();
Write table names you want, and initialize the select to get the result of fields.
from d1 in DealerContrac join d2 in DealerContrac on d1.dealearid equals d2.dealerid select new {dealercontract.*}
One Best example
Table Names : TBL_Emp and TBL_Dep
var result = from emp in TBL_Emp join dep in TBL_Dep on emp.id=dep.id
select new
{
emp.Name;
emp.Address
dep.Department_Name
}
foreach(char item in result)
{ // to do}

Categories

Resources