compare two list in linq - c#

i'm having to two tables, which i need to compare both the table.
Let say table 1) Student profile 2) staff list.-- in this each staff has their student id , like many row
I need to get the current staff who log in's student id which may be many row.
And the resulted student profile from table 1.

Based on what you're describing the Staff table has multiple entries (at least 1) for each staff member, and those entries have a unique StudentID mapping staff to student. Something like this:
StaffID = 1, StudentID = 3
StaffID = 1, StudentID = 21
StaffID = 2, StudentID = 45
...
With the above type of setup, you can grab the list of students that belong to the currently signed in staff user, then query the student table for matching students:
int staffID = 1; // current staff user
var staffStudents = StaffTable.Where(s => s.StaffID == staffID)
.Select(s => s.StudentID);
var query = StudentTable.Where(student =>
staffStudents.Any(id => id == student.StudentID));

Related

How to group by with left join by multiple columns using linq and get count of grouped records?

Lets say we have:
Employee class (prop: EmployeeID, EmployeeName, DepartmentID, Department - as navigation prop) and Department class (prop: DepartmentID, DepartmentName, Employees - as navigation prop).
The relationship between this two tables is one to many.
Now the concrete example:
Employee table
EmployeeID EmployeeName DepartmentID
1 Peter 1
2 Anna 1
3 John 2
Department table
DepartmentID DepartmentName
1 IT
2 Marketing
3 HR
The final result should be showing every department (DepartmentID, DepartmentName, NumOfEmployees) regardless does it have an employees with number of employees in the department, for example: 1, IT, 2 | 2, Marketing, 1 | 3, HR, 0.
My syntax was:
var dbContext.Departments.Include(d => d.Employees).
GroupBy(d => new { d.DepartmentID, d.DepartmentName }).
Select(x => new {
DepartmentID = x.Key.DepartmentID,
DepartmentName = x.Key.DepartmentName,
NumOfEmployees = x.Count()
}).ToList();
The problem is that attribute NumOfEmployees is assigned with 1 for every department, and don't know why.
How would correct lambda expression LINQ syntax look like?
I would say that you don't need GroupBy here and can do as simple as:
var result = dbContext.Departments
.Select(x => new
{
DepartmentID = x.DepartmentID,
DepartmentName = x.DepartmentName,
NumOfEmployees = x.Employees.Count()
})
.ToList();

If entity exists return a value in Entity Framework

I have Two tables "Customer" table and "Blacklist" customer table.
When i blacklist a customer i put the customerid as a foreign key to Blacklist table.
What i want to do is I need to find the Customer by "CusId" in the Customer Table.
I retrieve Name,Area,Telephone,Email from Customer table. When i retrive it, it should also check whether the customer id is in the black list customer table too.
depending on the existance it should pass a boolean value.
Final result should have total 5 columns.
(Name,Area,Telephone,Email,IsBlacklist).
Please help me to code this Entity Framework C#.
Thanks in advance.
Customer
---------
(CusId,Name,Telephone,Email)
Blacklist
---------
(CusId)
you can use navigation property of blacklist, that is exist on customer :
var customer = Customer.Select(u => new
{
u.Name,
u.Area,
u.Telephone,
u.Email,
Blacklist = u.Blacklist.Any()
})
.ToList();
To start you off:
var customer =
from c in Customer
where c.CusId == yourId
select new
{
c.Name, c.Area, c.Telephone, c.Email,
IsBlacklist = Blacklist.Any(b => b.CusId == yourId)
};

Entity Framework: Updating join tables

I have following table setup:
Order (ID)
Product (ID) [where ProductID 1 and 2 already exist]
OrderProduct (OrderId, ProductID) [two keys FK'ng to Order and Product tables]
And I'am trying to add a record to Order table assigning 2 products in to the order as follows:
var order = new Order();
order.Products.Add(new Product {ID=1});
order.Products.Add(new Product {ID=2});
db.SaveChanges();
The problem is: When saving the order, two Products are getting inserted in to the DB, instead of referring to the product records that already exists.
Please help. Thanks.
You should use db instead of creating new Product, like in this example:
var order = new Order();
order.Products.Add(db.Products.First(p => p.ID = 1));
order.Products.Add(db.Products.First(p => p.ID = 2));
db.SaveChanges();
Or, you need to "Update Reference" after product creation.
you can do something like this:
var product = new Product() { ID = 1 };
db.Attach(product);
order.Products.Add(product);

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();

Create an unique ID for multiple rows SQL

I have a number of user ID's. I am inserting these into a group table which will contain a column for the user's ID and the group ID. This will allow me to use the query "SELECT user_id FROM groups WHERE group_id = '3';" to retrieve user ID's of all the members of group 3.
My problem is that I currently have a list of all users IDs, which I got from a form, using the statements :
int i = 0;
String[] names = { Request.Form["usernames"]Split(' ') }; //retrieving names from form
List<int> user_ids = new List<int>();
foreach(string name in names){
int user_id = db.QueryValue("SELECT user_id FROM users WHERE username = name");
user_ids.Add(user_id); //now I have a list of all user_ids
}
I now wish to insert this data into the groups table, where all of the user_id values in the list will have the same group_ID. How can I do this?
//create a group from users
"INSERT INTO group (group_id, user_id) VALUES(?,?);
What you are talking about is a many-many relationship. You already have a users table:
**users**
userid
username
You need an additional table in the middle. The group table will just have something like:
**group***
groupid
groupName
You would then have a table in the middle. This table would look something like this:
**user_groups**
userid
groupid
You could still use your code to insert a user,
int i = 0;
String[] names = { Request.Form["usernames"]Split(' ') }; //retrieving names from form
List<int> user_ids = new List<int>();
foreach(string name in names){
int user_id = db.QueryValue("SELECT user_id FROM users WHERE username = name");
user_ids.Add(user_id); //now I have a list of all user_ids
}
After this, you would insert a group:
insert into group(groupName) values("Sample Group")
Then you could retrieve the group id and use that to insert into user_groups
select groupid from group where groupname="Sample Group"
insert into user_groups(userid,groupid) values(...
Also, the table structure should include primary keys and foreign keys (much like #sixlettervariables' answer)
In order to make this cleaner, you'll probably want to refactor your database setup slightly such that a third table relates users to groups:
users (user_id pk, ...)
groups (group_id pk, ...)
membership (user_id fk, group_id fk) unique(user_id, group_id)
When you needed to make a new group you simply insert into the groups table, obtain the group_id, and use that to populate the membership table for each of the users in that group.
You can use the select as the input to the insert
INSERT INTO group (group_id, user_id)
SELECT 1, user_id FROM users WHERE username in ("name1", name2")
You can join the names array back together with some commas.
You will need to iterate the user_ids list and do a separate insert statement for each user id.
You can insert all of the User ID's from one table into another using a sub-select and union statement as follows:
INSERT INTO group_table_name([user_id]) SELECT [user_id] FROM table_name
UNION ALL
By the way, you might want to change that table name since "group" is a keyword in SQL Server. Just a tip.
Insert Into GroupTable (GroupId, UserID) Select GroupID, USerID from UserTable group by GroupID, UserID)
This would work :)
Assuming you already know 3, you can do this without pulling the user ids into a local list and then inserting them individually (put in quotes specifically because the OP has their query in a similar string):
"INSERT dbo.group(group_id, user_id)
SELECT 3, user_id
FROM dbo.users
WHERE username = name;"
If you don't already know the group id, then please explain how you determined the group id should be 3.
EDIT based on further info.
CREATE TABLE dbo.Groups
(
GroupID INT IDENTITY(1,1) PRIMARY KEY,
GroupName NVARCHAR(255) NOT NULL UNIQUE
);
CREATE TABLE dbo.GroupUsers
(
GroupID INT NOT NULL FOREIGN KEY
REFERENCES dbo.Groups(GroupID),
UserID INT NOT NULL FOREIGN KEY
REFERENCES dbo.Users(UserID),
PRIMARY KEY(GroupID, UserID)
);
Now when you want to create a new group and add users to it:
DECLARE #GroupID INT;
INSERT dbo.Groups(GroupName) SELECT N'whatever (unique)';
SELECT #GroupID = SCOPE_IDENTITY();
Now you can loop through each user id:
INSERT dbo.GroupUsers(GroupID, UserID) SELECT #GroupID, <userid>;

Categories

Resources