Select items with the same foreign key - c#

I have a question regarding Linq in C#.
Let's say that I have 3 tables "Company", "Employee" and "Job".
Company
--------
Id - int (PK)
Name - string
Employee
--------
Id - int (PK)
CompanyId - int (FK on Company.Id)
Name - string
Job
--------
Id - int (PK)
CompanyId - int (FK on Company.Id)
EmployeeId - int (FK on Employee.Id)
Name - string
Something like that:
enter image description here
The important thing is that every work must be connected to a company but not necessarily to an employee. However, each employee must be connected to a company. For example we can have racord like that:
Company
--------
Id Name
1 'A'
2 'B'
3 'C'
Employee
--------
Id CompanyId Name
1 1 'A'
2 1 'B'
3 2 'C'
Job
--------
Id CompanyId EmployeeId Name
1 1 1 'clean'
2 1 2 'wash'
3 2 2 'buy'
4 3 NULL 'sell'
And now with linq I would like to get all jobs that are assigned to this employee and other employees from the same company.
So in this case it will should are jobs with id 1 and 2 becouse employee 1 is assigned to company 1 and job with id 2 also has assigned to this company. How could I achieve this using linq but something like this:
_context.Job.Where (x => x)
It is important to make only one query to the database.
Tkanks.

You can simplify the problem by thinking of it in two steps: find the company for a given employee, find all the jobs for that company:
var companyToFind = from e in Employee
where e.Id == empToFind
select e.CompanyId;
var jobsToFind = from j in Job
where companyToFind.Any(cid => cid == j.CompanyId)
select j;
In LINQ to SQL, EF Core 2.2 and EF Core 3.x the Any is translated to an EXISTS query in SQL.
Note since you know there should be only one answer to companyToFind, sending two queries to the database may be more efficient.
For LINQ to SQL or EF Core 3.x, you could also nest the first query and reduce to a single result:
var jobsToFind = from j in Job
where (from e in Employee
where e.Id == empToFind
select e.CompanyId).First() == j.CompanyId
select j;

Related

Get Multiple Values for one variable output in stored procedure

These are my classes
Public Class Student
{
Public int Id{get;set;}
public string Name {get;set;}
}
Public Class Department
{
Public int Id{get;set;}
public string Name {get;set;}
public IList <Student> StudentList{get;set;}
}
These are my tables
Student Table
Id |Name |Department
-----------------
1 |aa | 1
2 |bb | 1
3 |cc | 2
Department Table
ID | Name
----------
1 | xxx
2 | yyy
I need the all data of department with the corresponding list of student by using stored procedure
CREATE PROCEDURE test
(
)
AS
BEGIN
select Id as Id,
Name as Name,
----here I need all the corresponding data from student table as StudentList
from Department
Is it possible.. If so Please help me.
Apparently I what want is I want to write another procedure and call it for StudentList,Is it possible
Use join, i choose Left Join here so in case if department does not have corresponding students it will still be retrieved.
SELECT d.ID
,d.Name
,s.ID
,s. Name
FROM Deparment d
LEFT JOIN Student s ON s.Department = d.ID
So from your example the query will return the following result :
ID, Name, Student ID Student Name
1 xxx 1 aa
1 xxx 2 bb
2 yyy 3 cc
Assuming that your stored procedure will accept department id as parameter and retrieve all students under this department, just add a condition in your query
WHERE d.ID = #DeptID
As #Eugen said, just process the result in your application.
What you describe can be done, but it is not the normal process. You can use for xml to return a column where all of the student information is encoded. Note that while this results in all of the data you want being returned in a single row, you will have to create and populate all of your objects by hand. None of the ORM's like Entity Framework or nHibernate will populate both your department and students. In fact, you will probably end up parsing a string by hand in order to create your students.
The most common practice today would be to use Entity Framework and let it do all of the work for you.
Here's some code to show how you can do as you request. Again, note that this is not recommended, and that it's just one way of doing this:
create table #s (id int, name varchar(max), departmentId int);
insert into #s (id, name, departmentId)
select * from (values (1 , 'aa', 1) ,(2 , 'bb', 1) ,(3 , 'cc', 2)
) g(id, name, departmentId);
create table #d (departmentId int, name varchar(max));
insert into #d (departmentId, name) select * from (values
(1 , 'xxx') ,(2 , 'yyy')
)g(departmentId, name)
select *, (select id, name, departmentId
from #s s where s.departmentID = d.departmentId for xml path
)students
from #d d
drop table #d
drop table #s;
Students for deparment 1 =
<row><id>1</id><name>aa</name><departmentId>1</departmentId></row>
<row><id>2</id><name>bb</name><departmentId>1</departmentId></row>
In particular, you may find this a bit heavy, 2016 should be able to do something similar with JSON, but if you'd like that in the meantime, you'll have to customize the output yourself. It can be done, and wouldn't be too difficult.

what would be the Query in MS-Access for my following requirement?

i want to fetch all the records having max product id from product table. the records in the product table are stored as category wise like following
Product id Category id Product name Product image
1 1 product 1 path
2 1 Product 2 path
1 2 Product 1 path
2 2 Product 2 path
3 2 Product 3 path
1 3 Product 1 path
and i have Category table like following
Category id Category name
1 Category 1
2 Category 2
3 Category 3
so i need to write query that return all records of max product in each category (1,2,3 here in this example) so we'll get the result like
# Product id Category id Product name Product image
1. 2 1 product 2 path
2. 3 2 product 2 path
3. 1 3 product 1 path
note:- product id is primary key and generated according to it's category
category id is foreign key in product table.
i am using this query/database in my C# application. I am using MS-Access.
Ok this will help:
"SELECT * From Product WHERE Categoryid=(SELECT Max(Count(*)) from product group by Categoryid)"
this should help
SQL Server -
select p.* from
(
select max(productid) productid,categoryid from products group by categoryid
) a join products p on p.productid = a.productid
and p.categoryid = a.categoryid
ACCESS -
select [p].* from
(
select max(productid) as pid,categoryid from products group by categoryid
) as [a] inner join [products] as [p] on [p].[productid] = [a].pid
and [p].categoryid = [a].categoryid

Populate dropdown from two tables with differentiation between them

I am populating a combobox in C# & SQL.I have two tables to get data from them.
Table1
Id CategoryName
1 Salary
2 Utility
3 Other
Table2
Id SubCategoryName CatId
1 XYZ Salary 1
2 YY Salary 1
3 Car Exp 3
Now i want to show them all in a dropdown so that User select any of them and then i will save its Id.
How i will Know that selected Id is from Table1 OR Table2 ?
You will have to play around with fake id's. For example, you could create a new class with a new Id and map that new id to the tables manually. For example:
Class DisplayItem
Id 1 Name Salary
Id 2 Utility
Id 3 Other
Id 4 XYZ Salary
ID 5 Y Salary
Id 6 Car Exp
Then you will need code that looks like this
public int GetTableId(int DisplayItemId)
{
if (DisplayItemId < 4)
return 1;
return 2;
}

querying key value pair design table using EF

I have a table which is similar to Key-Value pair design structure. I would like to query the table based on the key and value, but I am facing some problem. Below is my table structure and expected output.
Table 1:
ID KEY VALUE
1 NAME abc
2 AGE 12
3 DEPARTMENT CCB
4 NAME xyz
5 AGE 13
6 DEPARTMENT TSS
7 NAME cde
8 AGE 12
9 DEPARTMENT TMS
Table 2:
KeyId KeyName
1 Name
2 Department
3 Age
for easy understanding I entered directly the key names in Table 1, actually there exists a foreign key relation between table 1 and table 2.
Also table 2 can hold anything as KeyName not necessarily Name, Department and Age.
Expected output is : I need to get the data with the Name contains %c% and Age = 12.
Name Age Department
abc 12 CCB
cde 12 TMS
NOTE: I am looking for a EF solution i.e., linq query, not sql query.
Options I tried out, below is the query:
var temp = (from c in table1
where c.Name.Contains("C") || C.Age == 12
Select new { C.Name, C.Age })
Thought of applying "OR" condition so that I get both the condition satisfied and then filter using "AND" in the in-memory once I fetch the data from database. But I was not able to succeed.
Try this:
var result = input.Select((x,i)=>new {x,i})
.GroupBy(a=>a.i/3)
.Where(g=>g.FirstOrDefault().x.Value.Contains("c") &&
Convert.ToInt32(g.Skip(1).FirstOrDefault().x.Value) == 12)
.Select(g=> new {
Name = g.FirstOrDefault().x.Value,
Age = Convert.ToInt32(g.Skip(1).FirstOrDefault().x.Value),
Department = g.Skip(2).FirstOrDefault().x.Value
});
Not sure if it works in EF but looks like if it doesn't, you have to execute the query in client side with AsEnumerable() before appending any method after input.

Using lookup tables with Entity Framework

I've had to use a lookup table in an EF project and it took me a bit of tinkering to get it working but I'm unsure how to query something.
If I have three tables (this is a test project to illustrate the question):
Person
------
ID - Int - PK
PersonName - varchar[50]
and
Skill
-----
ID - Int - PK
SkillName - varchar[50]
which are linked by a lookup table:
PS_Lookup
---------
ID - Int - PK
PersonID - Int - FK : Person.ID
SkillID - Int - FK : Skill.ID
Now, if I want to return all users who have a skill of ID 1 I've worked out I can do:
var result = (from p in context.People
select new
{
PersonID = p.ID,
PersonName = p.PersonName,
FirstSkill = (from s in p.PS_Lookup
where s.ID == 1
select s.SkillName),
}).ToList();
My question is, what do I need to change on the above query just to return the PersonName and PersonID of everyone who has the skill with the ID 1?
i.e. Not returning "FirstSkill". I don't need the name as I know what FirstSkill is and I can't see what I have to do with the where clause.
You need to use where condition in your query:
var result = (from p in context.People
where p.PS_Lookup.Any(ps => ps.ID == 1)
select new { p.ID, p.PersonName })
.ToList();

Categories

Resources