How to get Users who only have some specific department id, Linq - linq

I have following two entities
public class User
{
public int UserId { get; set; }
public string UserName { get; set; }
public List<Department> Departments { get; set; }
}
public class Department
{
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
public List<User> Users { get; set; }
}
As you see, relationship between two objects is M:N.
I wanna get User who only have specific department ID, in this case, How to get users using Linq?
Thanks in advance

int requiredId = ...
var usersInReqdDept = Users.Where(u => u.Departments
.Any(d => d.DepartmentId == requiredId));
If the Departments list can be null, you will need a null-check in the Where clause.
If you want to search the Departments list instead,
int requiredId = ...
var usersInReqdDept = Departments.Single(d => d.DepartmentId == requiredId)
.Users;
Of course, this will throw an exception if such a department doesn't exist.

Related

LINQ query many to many relation with additional field in join table

I want to get all the records from Complaints either are assigned to users or not and list of all users that the complaint is assigned to grouped by each complaint with LINQ query Left join. these tables have many to many relation table with additional fields like Date etc. I tried a lot pleas if some one help me for this query.
thanks in advance
public class Complaint
{
[Key]
public int Id { get; set; }
[Required]
public string? Name { get; set; }
[Required]
public string? Email { get; set; }
[Required]
public string? Complaint{ get; set; }
public ICollection<AsignComplaintToUsers> asignComplaintToUsers { get; set; }
}
public class ApplicationUser : IdentityUser
{
[Column(TypeName = "nvarchar(100)")]
public string? FirstName { get; set; }
[PersonalData]
[Column(TypeName = "nvarchar(100)")]
public string? LastName { get; set; }
public ICollection<AsignComplaintToUsers> asignComplaintToUsers { get; set; }
}
public class AsignComplaintToUsers
{
[System.ComponentModel.DataAnnotations.Key]
public int Id { get; set; }
public int ComplaintId { get; set; }
[ForeignKey("ComplaintId")]
public Complaint complaint { get; set; }
public string? AsignToId { get; set; }
[ForeignKey("AsignTo")]
public ApplicationUser applicationUser { get; set; }
public string? AsignById { get; set; }
}
with this query I solved the problem
var xyz = (from c in _context.complaints
join AC in _context.asignComplaintToUsers
on c.Id equals AC.ComplaintId into temp
from t in temp.DefaultIfEmpty()
join AppUser in _context.applicationUsers
on t.AsignTo equals AppUser.Id into temp2
from t2 in temp2.DefaultIfEmpty()
select new
{
complaint = c,
asugnSugessionTousers = t,
usersWhoAsignedComplaints = t2
}).ToList();

Checking grandchildren records to return grand-parent. Linq

I have different roles and each user can have multiple roles. Each role is connected to customer record in different way, e.g. a business analyst has many-to-many relation to project and each customer has many projects; whereas a customer record can have only one project manager associated to it.
public class Customer
{
public CustomerProjectManager ProjectManager { get; set; }
public ICollection<Project> Projects{ get; set; }
...
}
public class Project
{
public ICollection<ProjectBusinessAnalyst> BusinessAnalysts { get; set; }
public ICollection<ProjectDeveloper> ProjectDevelopers { get; set; }
...
}
public class ProjectDeveloper
{
public int Id { get; set; }
public Project Project{ get; set; }
public int ProjectId { get; set; }
public string DeveloperId { get; set; }
public string DeveloperEmail { get; set; }
public string DeveloperName { get; set; }
}
public class CustomerProjectManager
{
public int Id { get; set; }
public ICollection<Customer> Customers { get; set; }
public string ProjectManagerId { get; set; }
public string ProjectManagerEmail { get; set; }
public string ProjectManagerName { get; set; }
public CustomerProjectManager()
{
Customers = new List<Customer>();
}
}
I need to fetch customer records on basis of roles. To explain further, I need to combine multiple customer lists fetched on the basis of different roles assigned to a single user. I am unable to form right linq query.
I have a sample query, mentioned below, which sometimes returns the right records but if I have a new user and no customers are assigned to this user, the query returns all existing customers. Its important for me that all the combination and filtration is done in Iqueryable
Please help!
public async Task<List<Customer>> FetchCustomers(string userId, List<string> userRoles, string userEmail)
{
if (userRoles.Contains("Admin"))
{
customer = _context.Customers;
}
else if (userRoles.Contains("Project Manager") ||
userRoles.Contains("Business Analyst") ||
userRoles.Contains("Developer"))
{
if (userRoles.Contains("Project Manager"))
{
customers = customers.Where(c => c.ProjectManager.ProjectManagerId == userId
|| c.Projects.Any(op =>
op.ProjectsCompleted.Any(assignee =>
assignee.UserId == userId)));
}
if (userRoles.Contains("Business Analyst"))
{
var allPossibleCustomers = _context.Customers.Where(c =>
c.Projects.Any(op => op.BusinessAnalysts.Any(ba => ba.BusinessAnalystId == userId)));
customers = customers?.Union(allPossibleCustomers) ?? allPossibleCustomers;
}
if (userRoles.Contains(Roles.Developer.GetDescription()))
{
var allPossibleCustomers = _context.Customers.Where(c =>
c.Projects.Any(op => op.PREDevDevelopersAssigned.Any(ba => ba.DeveloperId == userId)));
customers = customers?.Union(allPossibleCustomers) ?? allPossibleCustomers;
}
}
var listData = await PagingList<Customer>.CreatePageAsync(customers, page, limit);
return listData;
}
Apparently I was trying to return the wrong list. The linq query is correct.

How to join 3 tables in linq and get some not included fields in query

I'm implementing asp.net core project. I have 3 tables Apiapp, ApiAppHistory and EntityType. There are three fields with the names SentType, Status and Reason in ApiAppHistory and those fields are of kind Id (int type) in APIApphistory. I joined ApiApp and ApiAppHistory tables in order to get those three fields from ApiAppHistory but because they are of kind int and are unclear when showing the result to the user, I join them with EntityType table which has their related name. In the select part of my query, in addition to ApiApp fields I also need to have SentType, Status and Reason value fields.
Here below is my incomplete query:
var qq = _context.Apiapp
.Include(a => a.Api)
.Include(a => a.Application)
.Include(a => a.Data);
var t12 = (from r in qq
from b in _context.ApiAppHistory
from s in _context.EntityType
where r.LastRequest== b.Id && b.SentType == s.Id
&& b.Reason == s.Id
&& b.Status == s.Id
select new { r, s.name for Reason, s.name for
SentType ,s.name for Status});
I want in select part of my query, obtain name of the fields that I specified from the EntityType table. However, I don't know how to do it. I appreciate if someone helps me.
Here is my EntityType table:
Here are my APIAppHistory and EntityType class model:
public partial class ApiAppHistory
{
public int Id { get; set; }
public int? SentType { get; set; }
public int? Reason { get; set; }
public int? Status { get; set; }
public virtual Apiapp ApiApp { get; set; }
public virtual EntityType StatusNavigation { get; set; }
public virtual EntityType SentTypeNavigation { get; set; }
public virtual EntityType ReasonNavigation { get; set; }
}
public partial class EntityType
{
public EntityType()
{
ApiAppHistoryStatusNavigation = new HashSet<ApiAppHistory>();
ApiAppHistorySentTypeNavigation = new HashSet<ApiAppHistory>();
ApiAppHistoryReasonNavigation = new HashSet<ApiAppHistory>();
}
public int Id { get; set; }
public string Name { get; set; }
public string EntityKey { get; set; }
public virtual ICollection<ApiAppHistory> ApiAppHistoryStatusNavigation { get; set; }
public virtual ICollection<ApiAppHistory> ApiAppHistorySentTypeNavigation { get; set; }
public virtual ICollection<ApiAppHistory> ApiAppHistoryReasonNavigation { get; set; }
}
}

How to apply Nested Select using Linq

I'm working with nested select and seems like what i am doing is not correct!.
I'm trying to retrieve all the Topics items.
public class Employee
{
public int Id{ get; set; }
//....other fields....
//......
public IList<Topics> Interest { get; set; }
}
public class Topics
{
public int Id { get; set; } ;
public string Name { get; set; } ;
//other fields
}
employeeItems = (from _emp in employees
select new Employee
{
EmpId = _emp.mediaId,
EmpName = _emp.mediaType,
......................
Interest = (from _emp1 in employees.Interest //has few rows
select new Topic
{
Id = _emp1.Topics[0].Id, //.<int>("id"), <<<ERROR
Name = _emp1.Topics[0].Name //["name"] <<<ERROR
}).ToList()
}).ToList();
}
Interest = (from topic in _emp.Interest.SelectMany(i=>i.Topic) //has few rows
select new Topic
{
Id = topic.Id, //.<int>("id"), <<<ERROR
Name = topic.Name //["name"] <<<ERROR
})
public class Employee
{
public int Id{ get; set; }
//....other fields....
//......
public IEnumberable<Topics> Interest { get; set; }
}
Leave the property as IEnumberable and don't do .ToList() inside the query. And it seems to me your data structure is employee has multiple interests and each interest has mulitple topics, that's why I used selectmany, but you can adjust it if I'm wrong with the data.

EF 4.1 POCO query

I have this POCO and I want to return a list of the users in a particular company.
public class Company
{
public AccreditedCompany()
{
this.Branches = new HashSet<Branch>();
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity), ScaffoldColumn(false)]
public int CompanyId { get; set; }
public bool Active { get; set; }
public virtual ICollection<Branch> Branches { get; set; }
}
public class Branch
{
public Branch()
{
this.Users = new HashSet<User>();
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity), ScaffoldColumn(false)]
public int BranchId { get; set; }
public int CompanyId { get; set; }
public string Name { get; set; }
public string ContactName { get; set; }
public virtual Company Company { get; set;}
public virtual ICollection<User> Users { get; set; }
}
public class User
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity), ScaffoldColumn(false)]
public int UserId { get; set; }
public int BranchId { get; set; }
public string ComputerSN { get; set; }
public string CameraSN { get; set; }
public virtual Branch Branch { get; set; }
}
This is my LINQ query:
var company = (from u in objDataContext.Companies.Include(c=>c.Branches.Select(v=>v.Users))
where u.CompanyId == 8 select u).FirstOrDefault();
IQueryable<User> users = (from j in company.Branches select j.Users);
I have this compilation error on the second query:
Error 2 Cannot implicitly convert type
'System.Collections.Generic.IEnumerable>'
to 'System.Linq.IQueryable'. An explicit conversion exists (are
you missing a cast?)
I want to get a list of the users, similar to a plain SQL statement like
SELECT dbo.Users.* FROM Branches
INNER JOIN dbo.Users ON dbo.Branches.BranchId = dbo.Users.BranchId
INNER JOIN dbo.Companies ON dbo.Branches.CompanyId = dbo.Companies.CompanyId
WHERE (dbo.Companies.CompanyId = 8)
Thanks in advance.
Your user query could be:
IEnumerable<User> users = company.Branches.SelectMany(branch => branch.Users);
This will return all users in any branch of the company.
It looks to me like you could just use:
IQueryable<User> users = objDataContext.Users
.Where(u => u.Branch.CompanyId == 8);
I notice you have both Company and CompanyId on your Branch entity, though. That seems redundant, even though it simplifies this query slightly. You should be able to get rid of Branch.CompanyId and User.BranchId and just use the entity associations.

Resources