Getting employees in each dept using LINQ LAMBDA - c#

I am trying to join two tables employee and department using LINQ and trying to get results in given below image format. Can some one help how to achieve this.
how to achieve employees present in each department.
Here is my code
var EmpList = (from d in Department
join e in Employee on d.ID equals e.ID
select new
{
ID = d.ID, Name = d.Name, Location = d.location, Employess =
e.FirstName, e.LastName, e.Gender
});
The above code not fully written. I am not getting any ideas how to achieve this.
var elist = from d in db.Departments
join e in db.Employees on d.ID equals e.ID
group d by e.DepartmentId into g
select new { Details = g };

Assuming that you have a structure like this:
var depts = new[] {
new Dept { ID = 1, Name = "IT", Location = "New York" },
new Dept { ID = 2, Name = "HR", Location = "London" },
new Dept { ID = 3, Name = "Payroll", Location = "Sydney" }
};
var employees = new[] {
new Employee { ID = 1, FirstName = "Mark", DeptID = 1 },
new Employee { ID = 2, FirstName = "Steve", DeptID = 3 },
new Employee { ID = 3, FirstName = "Ben", DeptID = 1 },
new Employee { ID = 4, FirstName = "Philip", DeptID = 2 },
new Employee { ID = 5, FirstName = "Mary", DeptID = 2 },
new Employee { ID = 6, FirstName = "Valarie", DeptID = 3 },
new Employee { ID = 7, FirstName = "John", DeptID = 1 }
};
You can use LINQ Join and GroupBy to get the desired data:
var result = depts
.Join(employees.GroupBy(x => x.DeptID), dept => dept.ID, empGroup => empGroup.Key,
(dept, empGroup) => new {
Name = dept.Name,
Location = dept.Location,
Employees = empGroup.ToArray()
});
Or the same in SQL-like syntax:
var result = from dept in depts
join empGroup in (
from e in employees
group e by e.DeptID into g
select g
) on dept.ID equals empGroup.Key
select new {
Name = dept.Name,
Location = dept.Location,
Employees = empGroup.ToArray()
};
What does this actually do?
Employees are grouped by DeptID.
Departments are joined with this grouping and result into a collection of anonymous objects of desired format. Of course, you can use a strongly-typed class.

public class Meta
{
}
public partial class Empolyees
{
public string depart
{
get
{
EmpolyeeEntities db = new EmpolyeeEntities();
var empid = db.Empolyees.Select(e=>e.Department).SingleOrDefault();
var dpname = db.Department1.Where(x => x.Id == empid).Select(f => f.Department).SingleOrDefault();
return dpname.ToString();
}
}

Related

need to filter data for `dataBefore` by comparing with 'dataAfter'

I have 2 list where I need filter data from dataBefore if not matching Name and SectionId available in dataAfter list.
var dataBefore = new List<School>
{
new School { Name = "N1", SectionId = null },
new School { Name = "N2", SectionId = new Guid("6aba7a38-8e61-472d-b4ce-b9fc2011af3f") },
new School { Name = "N3", SectionId = null },
new School { Name = "N4", SectionId = new Guid("ca663d45-04b8-4c80-96b6-c3760352a6ac") }
};
var dataAfter = new List<School>
{
new School { Name = "N1", SectionId = new Guid("5be0fc99-4826-4fbf-a190-b930af730b93") },
new School { Name = "N3", SectionId = null },
new School { Name = "N4", SectionId = null }
};
Expected output should be,
//N1 with sectionId = null
//N2 with SectionId = 6aba7a38-8e61-472d-b4ce-b9fc2011af3f
//N4 with SectionId = ca663d45-04b8-4c80-96b6-c3760352a6ac
Below query give me exact opposite result (only N3), how to get above expected result?
var x = dataBefore.Where(y => dataAfter.Any(z => z.Name == y.Name && z.SectionId == y.SectionId)).ToList();
var x = dataBefore.Where(y => !dataAfter.Any(z => z.Name == y.Name && z.SectionId == y.SectionId)).ToList();
You can get the result if the Any() returns false.

How to get aggregated values from a collection using values from the same collection as predicate

I have a list containing Employee Model Objects.
public List<EmployeeModel> EmployeeData()
{
return new List<EmployeeModel>()
{
new EmployeeModel(){ EmpID = 1, EmpSSN = 11, LName = "Motor", FName = "Mouse" },
new EmployeeModel(){ EmpID = 2, EmpSSN = 11, LName = "Motor", FName = "Mouse" },
new EmployeeModel(){ EmpID = 3, EmpSSN = 11, LName = "Motor", FName = "Mouse" },
new EmployeeModel(){ EmpID = 1, EmpSSN = 12, LName = "Cat", FName = "Auto" },
new EmployeeModel(){ EmpID = 2, EmpSSN = 12, LName = "Cat", FName = "Auto" },
};
}
I need to list each employee and their total EmpSSN occurrence so that the output will look like this:
Last Name: Mouse. Total EmpSSN: 3
Last Name: Cat. Total EmpSSN: 2
I can do something like this to get the names:
var name = data.EmployeeData().Select(x => x.LastName).Distinct();
However, I am not certain how to get the EmpSSN Count without writing extraneous code or using the same list twice, given I will not know the data in the list or have arguments to pass.
Rather than using Distinct, use GroupBy:
var name = data.EmployeeData()
.GroupBy(x => x.LastName)
.Select(g => new {
LastName = g.Key
, TotalEmpSsn = g.Count()
});
Since LastName is used as the group's key, Select gets groups combining records with identical last name. If you are looking to coult items within the group where a specific predicate would be true (e.g. EmpSsn above a certain number, etc.) you can supply that predicate to the Count() method.
I would group them first by LastName then call Sum() on the EmpSSN like so:
var data = EmployeeData()
.GroupBy(e => e.LastName)
.Select(e => new {
EmpID = e.Key,
EmpSSN = e.Select(emp => emp.EmpSSN).Sum()
});

Join multiple tables with nested type in subqueries

I need to create a "User" object from multiple tables and I want to do this in one EF query.
Here is my current query but I don't know how to fill the "Roles", "Groups" & "Permissions" properties, that are lists by the way.
cachedUsers = (from u in dbContext.Application_Users
join ug in dbContext.Application_UserGroups on u.UserID equals ug.UserID
join g in dbContext.Application_Groups on ug.GroupID equals g.GroupID
join gr in dbContext.Application_GroupRoles on g.GroupID equals gr.GroupID
join r in dbContext.Application_Roles on gr.RoleID equals r.RoleID
join rp in dbContext.Application_RolePermissions on r.RoleID equals rp.RoleID
join p in dbContext.Application_Permissions on rp.PermissionID equals p.PermissionID
select new SecurityUser()
{
ID = u.UserID,
UserName = u.UserName,
Roles = /*how to fill the list ? */(new Role
{
RoleID = r.RoleID,
RoleLevel = r.RoleLevel,
RoleName = r.RoleName,
Description = r.Description,
Trigram = r.Trigram,
Groups = /*how to fill the list ? */(new SecurityGroup
{
GroupID = g.GroupID,
GroupName = g.GroupName,
RoleName = r.RoleName,
}).ToList(),
Permissions = /*how to fill the list ? */(new Permission
{
PermissionID = p.PermissionID,
ConstantName = p.ConstantName,
Title = p.Title
})
.ToList()
}).ToList()
}
).ToList();
Can you help me doing this ?
Thanks a lot ! :)
You can create your object with nested objects this way:
var userList =
from r in recs
join c in Roles on r.UserID equals c.UserID into celft
from cnew in celft.DefaultIfEmpty()
join g in groups on cnew.GroupID equals g.GroupID into gleft
select new
{
UserID = r.UserID,
Name = r.Name,
Email = r.Email,
Roles = (from c1 in Roles
where c1.RoleID == cnew.RoleID
select new
{
c1.RoleID,
Grupo = (from g1 in groups
where g1.GroupID == c1.GroupID
select new
{
g1.GroupID,
g1.Name
}).ToList(),
}).ToList(),
};
This is the complete code, so you can test in a console app
class Program
{
static void Main(string[] args)
{
var recs = new List<Users> {
new Users { Name = "Alex", Email = "A", UserID= 1 },
new Users { Name = "Juan", Email = "B", UserID= 2 },
new Users { Name = "Peter", Email = "C", UserID= 3 },
new Users { Name = "Julios", Email = "D", UserID= 4 },
new Users { Name = "Dennis", Email = "E", UserID= 5 },
new Users { Name = "Jhon", Email = "F", UserID= 6 },
};
var groups = new List<Group> {
new Group { GroupID= 1, Name = "N1" },
new Group { GroupID= 2, Name = "N2" },
};
var Roles = new List<Roles> {
new Roles { UserID= 1, RoleID = 1 , GroupID = 1 },
new Roles { UserID= 1, RoleID = 2 , GroupID = 1},
new Roles { UserID= 2, RoleID = 3 , GroupID = 2},
};
var userList =
from r in recs
join c in Roles on r.UserID equals c.UserID into celft
from cnew in celft.DefaultIfEmpty()
join g in groups on cnew.GroupID equals g.GroupID into gleft
select new
{
UserID = r.UserID,
Name = r.Name,
Email = r.Email,
Roles = (from c1 in Roles
where c1.RoleID == cnew.RoleID
select new
{
c1.RoleID,
Grupo = (from g1 in groups
where g1.GroupID == c1.GroupID
select new
{
g1.GroupID,
g1.Name
}).ToList(),
}).ToList(),
};
foreach (var item in userList)
{
Console.WriteLine(string.Format("{0} {1} {2} {3}", item.UserID, item.Name, item.Email));
}
Console.ReadLine();
}
}
class Users
{
public int UserID;
public string Name;
public string Email;
}
class Roles
{
public int UserID;
public int RoleID;
public int GroupID;
}
class Group
{
public int GroupID;
public string Name;
}

MVC - Ordered List

I am trying to order the following list by descending but I can't seem to figure out how it is done:
var cust = item.Profiles.Select(c => new
{
id = c.CustId,
Name = c.Name
}).ToList();
ViewBag.Customers = new MultiSelectList(cust, "id", "Name");
This is what I have already tried:
var cust = item.Profiles.Select(c => new
{
id = c.CustId,
Name = c.Name.OrderByDescending();
}).ToList();
ViewBag.Customers = new MultiSelectList(cust, "id", "Name");
This is how the list is displayed on my view:
#Html.DropDownList("id", (MultiSelectList)ViewBag.Customers, new { #class = "form-control", id = "lstCustomer" })
Note: I am trying to sort the list in alphabetical order
var cust = item.Profiles.Select(c => new
{
id = c.CustId,
Name = c.Name
}).OrderByDescending(c=>c.Name).ToList();
Or
var cust = item.Profiles.OrderByDescending(a=>a.Name).Select(c => new
{
id = c.CustId,
Name = c.Name
}).ToList();
Using Linq:
var cust = item.Profiles.Select(c => new
{
id = c.CustId,
Name = c.Name
}).OrderByDescending(c => c.Name).ToList();
Or More Elegant (Query Syntax):
var cust = (from c in item.Profiles
orderby c.Name
select new
{
id = c.CustId,
Name = c.Name
}).ToList();
To do the same thing with query syntax:
var cust = (from c in item.Profiles
orderby c.Name descending
select new
{
id = c.CustId,
Name = c.Name
}
).ToList();

Dynamic linq query with nested groups

I'm trying to create nested group with dynamic query.
Following are my collection of data
var invoices = new List < Purchase > () {
new Purchase() {
Id = 1, Customer = "a", Date = DateTime.Parse("1/1/2009")
}, new Purchase() {
Id = 2, Customer = "a", Date = DateTime.Parse("1/2/2009")
}, new Purchase() {
Id = 3, Customer = "a", Date = DateTime.Parse("1/2/2009")
}, new Purchase() {
Id = 4, Customer = "b", Date = DateTime.Parse("1/1/2009")
}, new Purchase() {
Id = 5, Customer = "b", Date = DateTime.Parse("1/1/2009")
}, new Purchase() {
Id = 6, Customer = "b", Date = DateTime.Parse("1/2/2009")
}
};
This linq query is returning the desired result.
var tree = invoices.GroupBy(x => x.Date).Select(x => new
{
Key = x.Key,
Items = x.GroupBy(y => y.Customer).Select(y => new
{
Key = y.Key,
Items = y
})
}).ToList();
Below is the output of the above linq query
But I just need to group different columns in different order.
So that I try to create dynamic linq query. But my code block result not same as my previous linq query.
var groupedInvoiceItems = invoices.AsQueryable().GroupBy("new (Date, Customer)", "it");
You could do this with Generics. Just Pass in your Lambda to a generic method.
Something like:
private IEnumerable<PurchaseGrp> BuildList<TSource>(IQueryable<TSource> allRecords,
Func<TSource, string> selector)
{
var result = allRecords.GroupBy(x = > x.selector(x));
return result;
}
The return type could be a new Grouped type PurchaseGrp or the same as your source (Purchase).

Categories

Resources