Return navigation property within join query - c#

In building a patient appointment application I need to return patients with its navigation property patientDetails while those returned match a sessionId that is not directly deduced from the patient but rather from a series of other navigation properties. This in itself is not difficult, like plain SQL joins can be used, it's just that my navigation property patientDetails is never included.
The include path is correct, in case anyone asks.
using (DbEntities db = new DbEntities())
{
List<tblPatient> res = (from s in db.tblSessions
join b in db.tblBookings on s.id equals b.sessionId
join r in db.tblReferrals on b.referralId equals r.id
join a in db.tblAttendanceStatus on b.attendanceStatus equals a.id
join p in db.tblPatients.Include("tblPatientDetail") on r.patientId equals p.id
join pd in db.tblPatientDetails on p.patientDetailsId equals pd.id
where s.id == id
select p).ToList();
return res;
}
It appears to make no difference whether or not I include the .include.
What have I overlooked?

Includes are ignored when you use join or group by. You can change your query to use where instead
List<tblPatient> res = (from p in db.tblPatients.Include("tblPatientDetail")
where
(from s in db.tblSessions
join b in db.tblBookings on s.id equals b.sessionId
join r in db.tblReferrals on b.referralId equals r.id
join a in db.tblAttendanceStatus on b.attendanceStatus equals a.id
where r.patientId == p.id
where s.id == id
select 1).Any()
select p).ToList()

Related

Inner select query in linq query c#

I want to check values that are present in other table, not from fixed list or array. here is an example of what I need. Actually I am querying EF.
Database_EF db = new Database_EF();
var listA = (from a in db.a
where a.id in
(from b in db.b
join c in db.c on b.id equals c.id
where c.col1 equals 'something'
select b.id)
select a.id).ToList();
I am new to linq. Thanks.
Should be something like this:
var listA = (from a in db.a
where (from b in db.b
join c in db.c on b.id equals c.id
where c.col1 == "something"
select b.id).Contains(a.id)
select a.id).ToList();

How can I with LiNQ select items from a list based on another list?

I am creating a game, and my table layout looks like this:
dbPlayer:
Id (int)
...
dbGame:
Id (int)
Finished (bool)
...
dbGamePlayer:
GameId
PlayerId
...
Given a Players ID, how can I select all games that the player is involved in, but has not (true) finished?
This is what I've go so far:
from g in dbGame
join gp in dbGamePlayer on gp.GameId equals g.Id
join p in dbPlayer on p.Id equals gp.PlayerId
where p.Id == 1 && g.Finished == false
select g
But I'm getting errors all over the place. Sorry, I'm new at LINQ
Your LINQ Statement is wrong.
The joint object (gp) has to be on the right side of the equals-Statement.
join gp in dbGamePlayer on g.Id equals gp.GameId
Same applies to the second join:
join p in dbPlayer on gp.PlayerId equals p.Id
So the full statement should look like:
IEnumerable query = (from g in dbGame
join gp in dbGamePlayer on g.Id equals gp.GameId
join p in dbPlayer on gp.PlayerId equals p.Id
where p.Id == 1 && g.Finished == false
select g);
But the error
Name model is not in scope on the left side of equals.
Consider swapping the expression on the either side of equals.
should have told you that.

Can anyone reduce these 3 LINQ to SQL statements into one?

Ok so I am trying to get all the Companies assigned to BOTH courses that exist in a course mapping table.
The course mapping table has 2 FK CourseIDs, that point to two different courses in the same table.
Each course has a bundle, and the companies are assigned to bundles.
I am trying to select all the companies that are assigned to both bundles from both courses.
I have been able to do this (Edit: apparently not, because of the OR, can anyone fix this too?) using 3 different LINQ queries, but I am hoping there is a way to reduce it into one for both brevity and performance:
Bundle vegasBundle = (from cm in db.VegasToPegasusCourseMaps
join c in db.Courses on cm.VegasCourseID equals c.CourseID
join b in db.Bundles on c.BundleID equals b.BundleID
where cm.VPCMapID == CourseMapID
select b).FirstOrDefault();
Bundle pegasusBundle = (from cm in db.VegasToPegasusCourseMaps
join c in db.Courses on cm.PegasusCourseID equals c.CourseID
join b in db.Bundles on c.BundleID equals b.BundleID
where cm.VPCMapID == CourseMapID
select b).FirstOrDefault();
IQueryable<Company> companyAssigned = from cb in db.CompanyBundles
join c in db.Companies on cb.CompanyID equals c.CompanyID
where cb.BundleID == vegasBundle.BundleID || cb.BundleID == pegasusBundle.BundleID
select c;
return companyAssigned.ToList();
Here's your simplified query:
return (
from cm in db.VegasToPegasusCourseMaps
join cv in db.Courses on cm.VegasCourseID equals cv.CourseID
join bv in db.Bundles on cv.BundleID equals bv.BundleID // vegasBundle
join cp in db.Courses on cm.PegasusCourseID equals cp.CourseID
join bp in db.Bundles on cp.BundleID equals bp.BundleID // pegasusBundle
from cb in db.CompanyBundles // OR-Join must be in the where clause
join c in db.Companies on cb.CompanyID equals c.CompanyID
where cm.VPCMapID == CourseMapID
&& (cb.BundleID == bv.BundleID || cb.BundleID == bp.BundleID)
select c
).ToList();
[Update]:
Here's the query that matches your requirements. It will only match companies that match both courses.
return (
from cm in db.VegasToPegasusCourseMaps
join cv in db.Courses on cm.VegasCourseID equals cv.CourseID
join bv in db.Bundles on cv.BundleID equals bv.BundleID // vegasBundle
join cbv in db.CompanyBundles on bv.BundleId equals cbv.BundleId
join cv in db.Companies on cbv.CompanyID equals cv.CompanyID
join cp in db.Courses on cm.PegasusCourseID equals cp.CourseID
join bp in db.Bundles on cp.BundleID equals bp.BundleID // pegasusBundle
join cbp in db.CompanyBundles on bp.BundleId equals cbp.BundleId
join cp in db.Companies on cbp.CompanyID equals cp.CompanyID
where cm.VPCMapID == CourseMapID
&& cv.CompanyID == cp.CompanyID
select cv
).ToList();
Another thing: since you have the following relationship: Courses.BundleId => Bundles.BundleId => CompanyBundles.BundleId, you can actually join Courses to CompanyBundles and skip the Bundles join. But SQL probably does this anyway.
Here's a modification for your last query to ensure that you get companies that are enrolled in both bundles:
IQueryable<Company> companyAssigned =
from c in db.Companies
join vcb in db.CompanyBundles on c.CompanyID equals vcb.CompanyID
join pcb in db.CompanyBundles on c.CompanyID equals pcb.CompanyID
where vcb.BundleID == vegasBundle.BundleID && pcb.BundleID == pegasusBundle.BundleID
select c;
For combining the queries, you can look at Scott Rippey's answer.

How do I build up a LINQ => SQL / entities query (with joins) step-by-step?

I have the following two LINQ queries:
public int getJobsCount()
{
var numJobs =
(from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id
select j).Count();
return numJobs;
}
public List<Job> getJobs()
{
var jobs =
(
from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id
orderby j.issueDatetime descending
select new Job { x = j.field, y = c.field, etc }
).Skip(startJob - 1).Take(numJobs);
return jobs;
}
There's a lot of duplicate code in there - the "from", and "join" lines are identical, and I'll be adding in some "where" lines as well that will also be identical.
I tried adding a method that returned an IQueryable for the first part:
public IQueryable getJobsQuery()
{
var q =
from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id;
return q;
}
...but I get "a query body must end with a select clause or a group clause".
If I add a select clause on to the end off that function, I can't call count() on the result:
// getJobsQuery:
var q = from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id
select new { a = j.y, b = c.z }
// another method:
var q = getJobsQuery();
var numJobs = q.Count(); // "IQueryable doesn't contain a definition for count"
Is there a way to build up this query step-by-step to avoid duplicating a whole lot of code?
There are two ways of writing LINQ-queries, and though it doesn't really matter witch one you use it's good to know both of them cause they might learn you something about how LINQ works.
For instance, you have a set of jobs. If you were to select all jobs with an industryId of 5 (wild guess of data-types) you'd probably write something like this:
from j in dbConnection.jobs
where j.inustryId == 5
select j;
The very same query can also be written like this
dbConnections.jobs.Where(j => j.industryId == 5);
Now, I'm not here to preach saying one way is better than the other, but here you can clearly see how LINQ using the extension-methods syntax automatically selects on the iterated object (unless you do a select), whereas in the query-syntax you must do this explicitly. Also, if you were to add inn another where clause here it would look something like this:
from j in dbConnection.jobs
where j.inustryId == 5 // not using && here just to prove a point
where j.cityId == 3 // I THINK this is valid syntax, I don't really use the query-syntax in linq
select j;
While in the extension-methods you can just append more method-calls like so:
dbConnections.jobs.Where(j => j.industryId == 5)
.Where(j => j.cityId == 3);
Now this is good to know cause this means you can just put your linq-query inside a function an continue querying it. And all you need to do to make it work in your case is just explicitly select the starting variable j, or all the variables you need like so:
var q =
from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id;
select new {j = j, i = i, c = c, s = s, pt = pt };
return q;
Then you should be able to do for instance this:
getJobsQuery().Where(a => a.i.id == 5); // I used a as a name for "all", like the collection of variables
or using the query-syntax
from a in getJobsQuery()
where a.i.id == 5
select a;
Would this be better solved by returning a set of data (e.g. the common data) and querying for a subset of that data?
E.g. [pseudocode]
var allJobs =
(from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id
select j);
var myJobs = allJobs.OrderBy(j => j.issuedate).skip(expr).Take(allJobs.Count);
or similar...

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