Linq select Item where it is equal to ID in another table - c#

I am not sure how possible this is but I have two tables and I want to grab a value from table 2 via the value of table 1.
Table 1 has the a Foreign Key called "rank" which is an int. Table 2 has a value called "name" which is a string. Now Table 1's "rank" correlates to Table 2's "ID".
So when I say
var result =
db.Table1.Select(x => new { x.name, x.rank }).ToList();
//Bob - 2
I really want to say something like
var result =
db.Table1.Select(x => new { x.name, Table2.rank.Where(ID == x.rank) }).ToList();
//Bob - Gold
I am still new to LINQ though and I am not sure how to get rank's string value from the other table within a query like this.
EDIT
Tables I am using and their relational values.
User: ID (PK), s1elo (FK to PastElos), champ (FK to ChampionList), elo (FK to EloList)
PastElo: ID (PK), Rank
ChampionList: ID (PK), name
EloList: ID (PK), Rank
Working example for Users and PastElo
var result =
db.Users.Join(db.PastEloes,
x => x.s1elo, y => y.ID, (x, y)
=> new { y.Rank, x.name, x.other_items_in_Users }).ToList();
Note: PastElo is PastEloe's due to EF making everything plural when I synced up my DB, thus why User is also Users, I think that is referred to as the "context".

You could try something like the following:
var result = db.Table1.Join(db.Table2,
x=>x.rank,
y=>y.ID,
(x,y) => new { x.rank, y.Name }).ToList();
In the above linq query we make a Join between the two tables, Table1 and Table2 based on the association and then we select that we want.
Another way you could try to write this query would be the following:
var result = (from t1 in db.Table1
join t2 in db.Table2
on t1.rank equals t2.ID
select new { t1.rank, t2.Name, }).ToList();

Another way to do this would be to include your Database relationships in your C# entities. You could use EntityRef here. See the following documentation:
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql/linq/how-to-map-database-relationships

Related

LINQ join multiple tables by same column

I have one table Texting, that I need to join with another two tables Student and Staff to search for information about these 2 tables.
Student fields:
Id
Name
... and a bunch of other fields specific to student
Staff fields:
Id
Name
... and a bunch of other fields specific to staff
Texting fields:
Id
PersonId // contains either student ID or staff ID
PersonTypeId // indicates whether PersonId is of type student or staff (student = 1, staff = 2)
Now I need to write a linq query to search the table Texting either by student or staff name but I am stuck on the linq to achieve this.
var query = (from t in texting
join s in studentBo.GetListQuery()
on t.PersonId equals s.Id
join st in staffBo.GetListQuery()
on t.PersonId equals st.Id
where ...
select t);
This joins the tables together but it doesnt care what the PersonId type is so it's all mixed. How do i specify so that it joins the PersonId correctly according to the right PersonTypeId? It seems like nothing else can be appended on the on clause or where clause to make this happen = (.
So you have a name, and you want all Textings that refer to a Student with this name, and all Textings that refer to a member of Staff with this Name.
My advice would be to concat the Student textings with the Staff textings. You could do that in one big LINQ statements, however this would make it quite difficult to understand. So I'll do it in two steps, then Concat it in one query:
const int student = 1;
string name = "William Shakespeare";
var studentTextings = textings.Where(texting => texting.PersonTypeId == student)
.Join(students.Where(student => student.Name == name),
texting => texting.PersonId, // from every Texting take the foreign key
student => student.Id, // from every Student take the primary key
// parameter resultSelector:
// from every texting with its matching student make one new:
(texting, studentWithThisTexting) => new
{
// Select the Texting properties that you plan to use
Id = texting.Id,
...
}
In words: from all Textings, keep only those Textings that refer to a student, so you know that the foreign key refers to a primary key in the table of Students. From all Students keep only those Students that have the requested name.
Join all remaining Textings and the few remaining Students that have this name on primary and matching foreign key.
Do something similar for members of Staff:
const int staff = 2;
var staffTextings = textings.Where(texting => texting.PersonTypeId == staff)
.Join(staffMembers.Where(staffMember => staffMember.Name == name),
texting => texting.PersonId, // from every Texting take the foreign key
staffMember => staffMember.Id, // from every Staff member take the primary key
// parameter resultSelector:
(texting, staffMembers) => new
{
// Select the Texting properties that you plan to use
Id = texting.Id,
...
}
Now all you have to do is Concat these two. Be aware: you can only Concat similar items, so the resultSelector in both Joins should select objects of exactly the same type.
var textingsOfPersonsWithThisName = studentTextings.Concat(staffTextings);
There is room for improvement!
If you look closely, you'll see that the textings table will be scanned twice. The reason for this, is because your database is not normalized.
Can it be, that a Texting for a Student will ever become a Texting for a member of Staff? If not, my advice would be to make two tables: StudentTextings and StaffTextings. Apart from that queries will be faster, because you don't have to check PersonType, this also has the advantage that if later you decide that a StudentTexting differs from a StaffTexting, you can change the tables without running into problems.
If you really think that sometimes you need to change the type of a texting, and you don't want to do this by creating a new texting, you also should have two tables: one with StudentTextings, and one with StaffTextings, both tables having a one-to-one relations with a Texting.
So Students have one-to-many with StudentTextings, which have one-to-one with Textings. Similar for Staff and StaffTextings.
So Student [4] has 3 StudentTextings with Id [30], [34], [37]. Each of these StudentTextings have a foreign key StudentId with value [4]. Each StudentTexting refers to their own Texting with a foreign key: [30] refers to texting [101], so it has foreign key 101, etc.
Now if texting [101] has to become a texting for Staff [7], you'll have to delete the StudentTexting that refers to [101] and create a new StaffTexting that refers to Staff [7] and Texting [101]
By the way, since the combination [StudentId, TextingId] will be unique, table StudentTextings can use this combination as primary key. Similar for StaffTextings
You will have to merge Student and Staff tables, otherwise all your queries will be too complicated, since you will have to use Union
Person
Id
Name
PersonType
Texting
Id
PersonId
and query
var query = (from t in texting
join p in person
on t.PersonId equals p.Id
where ...
select t);
PS if you still want a query with 2 tables instead of one, you will have to post the real code.
You'll need to do these as two separate queries, project to a new type and then union the results. Messy, but here's how.
First get your students:
var textingStudents = (
from s in students
join t in texting on s.Id equals t.PersonId
where t.PersonTypeId == 1
select new { id = s.Id, personTypeId = 1, name = s.Name }).ToList();
Now get your staff in almost the exact same way:
var textingStaff = (
from s in staff
join t in texting on s.Id equals t.PersonId
where t.PersonTypeId == 2
select new { id = s.Id, personTypeId = 2, name = s.Name }).ToList();
Now you can union the two:
var allTextingPeople = textingStudents.Union(textingStaff);
If you need additional properties then add then to the anonymous type declared in the select statement - remember, the type will need to have the same properties in both the textingStudents and textingStaff result. Alternatively, define a class and do a select new MyUnionClass { ... } in both queries.
Edit
You're going to probably get into a world of hurt with the current approach you've outlined. If you're using a relational database (i.e. sql server) you almost certainly are not defining constraints such as foreign keys on your Texting table meaning you'll end up with ID clashes and will definitely end up with bugs later down the road. Best approach is probably to have one table to represent Staff and Student (let's call it Person with a column defining the "type" of person - the column itself will be foreign key link to another table with your list of PersonTypes

How to get two table value using Linq

I have two table one is Administrator table and another is Teacher table .
I want to display these both tables values in single Gridview .
I have make id as a primary key in Administrator table and make this tech_id as foreign key in Teacher table .
Now how to get these table values together in single gridview as shown in pic
Now please any body help me how to get these two value together using Linq .
I have try but I can't make any more
private void loadgri()
{
StudentDatabaseEntities empl = new StudentDatabaseEntities();
var query=from g in empl.Teachers
join m in empl.Administrators on g.id equals m.id
where m.username=="cs"
select new{
Name = g.username,
};
}
You don't need a join if you have already a navigation-property:
var query= from t in empl.Teachers
where t.Administrator.username == "cs"
select new { Teacher = t.username, Administrator = t.Administrator.username };
This is just an example, but you see that you can access all properties of both entities.
Don’t use Linq’s Join. Navigate!
To show all the teachers and their administrator, you don't have to use "join", you could just use the navigation property:
var query = from g in empl.Teachers
where g.Administrator.username=="cs"
select new {
Teacher_Id = g.Id,
Teacher_Name = g.username,
Administrator_Id = g.Id,
Administrator_Name = g.Administrator.username,
//etc...
};

how to get the max value of id from second table using join in entity framework in asp.net c#

I have two tables, from 1st table i want to get all records and from 2nd table i want the max id value of that record. I am using entity framework in asp.net c#.
i tried the below code but it takes only single record from first table i.e tblblogs. and leave all the records, how to get all those records by using this query? plz help me out I'll be very grateful to you. Thanks !
var query= (from c in db.tblBlogs join a in db.tblBlogMedias on c.id
equals a.BlogId where c.id==db.tblBlogMedias.Max(p=>p.id)
select new
{}
If I understood, you want to get an object with specific fields of Blogs and a list of tblBlogMedias.
You could try this code:
var query2 = (from c in db.tblBlogs
orderby c.Id descending
group c.tblBlogMedias by new { c.Id, c.Name } into gb //It will show Id and name of tblBlogs, you can use more fields if you want
select new {
Id = gb.Key.Id,
Name = gb.Key.Name, //I don't know if you have this field, but you should change it
SecondTable = gb.ToList()
})
.OrderByDescending(o => o.Id) //this orderby with FirstOrDefault() replace where c.id==db.tblBlogMedias.Max(p=>p.id)
.FirstOrDefault();

Problemin getting correct query result in asp.net using join

I am learning ASP.net and I have come to the point that I want to insert, update, delete records in a database.
Currently I am trying to read out values out of 2 tables using "join" but when I display the results in a grid the Foreign Key values are still like : 2, 1, 2,... Instead I want them to be to coresponding words.
This is the current query I am using:
from p in dc.Personeels join a in dc.Afdelingens on p.fk_personeel_afdeling equals a.pk_afdeling_id select p
Does anyone know what I am doing wrong?
Try this query
var query = from p in dc.Personeels
join a in dc.Afdelingens on p.fk_personeel_afdeling equals a.pk_afdeling_id
select new
{
id = p.id, // your id from table dc.Personeels
name = a.name // Name from table dc.Afdelingens
} into x
select x;

LinqtoSql Query In this scenario

Employee Table
Primary Key:EmployeeID
Machine Type Table
Primary Key: MachineTypeID
Machine Table:
Primary Key: MachineID
Foreign Key: MachineTypeID
Foreign Key: EmployeeID
Database structure is described above now I want to query on Machine Table and show following results.
I want to know how to write LinqtoSql query to achieve above table.. is join works here. Kindly help me.
If you have DB/Object Context named context, and also if you don't have navigations on entities(as King King says below your question), you can form a multiple-join query:
var result =
from m in context.Machine
join mt in context.MachineType on m.MachineTypeID equals mt.MachineTypeID
join e in context.Employee on m.EmployeeID equals e.EmployeeId
select new { m.MachineID, mt.Type, e.EmployeeName, m.Price, m.Male, m.Year };
var result = Machine
.Join
(
MachineType,
x=>x.MachineTypeID,
x.MachineTypeID,
(m,mt)=>new
{
m.MachineID,
m.EmployeeID,
m.Price,
m.Make,
m.Year,
mt.Type
}
)
.Join
(
Employee,
x=>x.EmployeeID,
x=>x.EmployeeID,
(m,e)=>new
{
m.MachineID,
MachineType = m.Type,
Employee = m.EmployeeName,
m.Price,
m.Make,
m.Year
}
);
Something like the below will get you started:
This uses navigation properties instead of joins.
var result = context.Machines.Where(x => x.EmployeeID == 3)
.Select(v => new
{
v.MachineID, // from Machines table
v.MachineTypes.MachineType, // from MachineTypes table
v.Employees.EmployeeName, // from Employees table
v.Price, // from Machines table
v.Make, // from Machines table
v.Year // from Machines table
});

Categories