Expression With and Union All to EF Core - c#

I want to convert this SQL query to EF Core code.
I don't want to use LINQ, any possibility?
with cat (id, id_parent, name) as
(
select id, id_parent, name
from categories
where categories.id = 9
union all
select e.id, e.id_parent, e.name
from dbo.categories e
inner join brands b on b.id_parent = e.id
);
select * from cat;

If I get your question correctly this would work for you:
var result = await _dbContext.Categories
.Where(x => x.Id == 9)
.Select(x => new { Id = x.Id, Parent = x.IdParent, Name = x.Name})
.Concat(
_dbContext.Categories.Join(_dbContext.Brands, cat=> cat.Id, brand=> brand.IdParent, (cat,brand)=>cat)
.Select(x => new { Id = x.Id, Parent = x.IdParent, Name = x.Name }))
.ToListAsync();

Related

How to USE LEFT JOIN, GROUP BY and SUM in LINQ and C#

I have 4 tables (Group, Student, Mark, StudentFile, and want to write my SQL query using LINQ in C#.
Here is my query
SELECT
S.Id,
S.FirstName,
S.LastName,
S.MiddleName,
SUM(M.CountOfPasses) CountOfPasses,
(SELECT SUM(CountOfPassesWithARespectful) FROM StudentFile WHERE StudentId = S.Id) WithARespectful
FROM Student S
LEFT JOIN Mark M ON S.Id = M.StudentId
GROUP BY S.Id, S.FirstName, S.LastName, S.MiddleName
I've already tried something like this:
var students = (from G in context.Group
let v = G.Id
from S in context.Student.Where(x => v == x.GroupId)
from F in context.StudentFile.Where(x => x.StudentId == S.Id).DefaultIfEmpty()
from M in context.Mark.Where(x => x.StudentId == S.Id).DefaultIfEmpty()
group new
{
F.CountOfPassesWithArespectful,
M.CountOfPasses,
S.Id
}
by new
{
S.Id,
S.FirstName,
S.LastName,
S.MiddleName,
S.StartCourse,
G.Name,
S.Alphagroup
} into GSF
select new DTOStudent
{
Id = GSF.Key.Id,
FirstName = GSF.Key.FirstName,
LastName = GSF.Key.LastName,
MiddleName = GSF.Key.MiddleName,
CountOfPasses = (int)GSF.Sum(p=>p.CountOfPasses),
WithRespectful = (int)GSF.Sum(x => x.CountOfPassesWithArespectful),
WithOutRespectful = (int)GSF.Sum(x => x.CountOfPasses) - (int)GSF.Sum(x => x.CountOfPassesWithArespectful),
Course = ClassMethods.GetAgeFromDates((DateTime)GSF.Key.StartCourse).ToString() +
ClassMethods.GetShortGroupName(GSF.Key.Name) + GSF.Key.Alphagroup.ToUpper()
}).Distinct().ToList();

LinQ select an object with a list as parameter

I'm using Linq queries to select from CRM 2013 with my webservice.
My final entity looks like this:
class FOO{
Guid fooId{get;set;}
String fooName{get;set;}
List<Car> fooCars{get;set;}
List<House> fooHouses{get;set;}
}
Where Car looks like this:
class Car{
Guid carId{get;set;
String carName{get;set;}
Guid carFooId{get;set;}
}
And House looks like:
class House{
Guid houseId{get;set;}
String houseName{get;set;}
Guid houseFooId{get;set;}
}
Now, my problem is the following:
I wanna query only once the crm and retrieve a list of FOO with all lists inside it. At the moment I do like this:
List<FOO> foes = crm.fooSet
.Where(x => x.new_isActive != null && x.new_isActive.Value = true)
.Select(x => new FOO(){
fooId = x.Id,
fooName = x.Name,
fooCars = crm.carSet.Where(c => c.fooId == x.Id)
.Select(c => new Car(){
carId = c.Id,
carName = c.Name,
carFooId = c.fooId
}).ToList(),
fooHouses = crm.houseSet.Where(h => h.fooId == x.Id)
.Select(h => new House(){
houseId = h.Id,
houseName = h.Name,
houseFooId = h.fooId
}).ToList()
}).ToList();
My aim is to use LinQ with the non-lambda queries and retrieve all the datas I need with a join and a group-by, but I don't really know how to achieve it, any tip?
Thanks all
I think what you are looking for is a group join:
var query= from f in crm.fooSet
join c in crm.carSet on c.fooId equals f.Id into cars
join h in crm.houseSet on h.fooId equals f.Id into houses
where f.new_isActive != null && f.new_isActive.Value == true
select new FOO{ fooId = f.Id,
fooName = f.Name,
fooCars=cars.Select(c => new Car(){
carId = c.Id,
carName = c.Name,
carFooId = c.fooId
}).ToList(),
fooHouses=houses.Select(h => new House(){
houseId = h.Id,
houseName = h.Name,
houseFooId = h.fooId
}).ToList()
};

Self Join or Inner Query in a table with Linq to SQL

I have two tables User & Employee.
+-------Supervisor----------+
SupervisorId
Password
+---------------------+
+-------Employee----------+
EmployeeId
EmployeeSupervisorId
EmployeeName
+---------------------+
This is what I am doing so far
SupervisorName = db.Employee.Where(m => m.EmployeeSupervisorId == m.SupervisorId).Select(q => q.EmployeeName).ToList()
I am not understanding the concept of how I join my Employee table to itself so that I can get a list of Employee and their corresponding Supervisor Name
You can do the below
SupervisorName = db.Employee
.Join(db.Supervisor,
emp => emp.EmployeeSupervisorId,
sup => sup.SupervisorId,
(emp, sup)=> new {SupervisorName = emp.EmployeeName})
.Select(x=>x)
.ToList();
SupervisorName = db.Employee.
Join(db.Supervisoer, e => e.EmployeeSupervisorId, s => s.SupervisorId, (e, s) => new { Employee = e, Supervisor = s}.
ToList().
Select(e => e.EmployeeName).
ToList();
You can use a simple subquery like this
var result = db.Employee.Select(e => new
{
Employee = e,
SupervisorName = db.Employee
.Where(s => s.EmployeeId == e.EmployeeSupervisorId)
.Select(s => s.EmployeeName).FirstOrDefault()
}).ToList();
Note that if you have EmployeeSupervisorId defined as a foreign-key pointing back to EmployeeId, the Linq2Sql will automatically create a EmployeeSupervisor property (which would be an Employee object)
var list = from e in db.Employee
// where e.......
select new {
Name = e.EmployeeName,
Supervisor = e.EmployeeSupervisor.EmployeeName,
// otherdetails = e......
}
If you haven't defined the foreign key, you have to specify it explicitly in the query:
var list = from e in db.Employee
join s in db.Employee on e.EmployeeSupervisorId equal s.EmployeeId
// where e.......
select new {
Name = e.EmployeeName,
Supervisor = s.EmployeeName,
// otherdetails = e......
}

Select inside select (SQL to lambda linq expression)

Select Label,
(SELECT COUNT(*) from [CourtSessions] cs where cs.iDCity = Cit.ID) as courts,
(Select COUNT(*) from [Cases] c inner join [CourtSessions] cs ON c.ID = cs.iDCase where cs.iDCity = Cit.ID) as csnatures
FROM Cities Cit
Group by Label, id
I tried this but it doesn't work
var data = db.Cities
.GroupBy(a => a.label)
.Select(g => new
{
city = g.Key,
sessions = db.CourtSessions.Include(p => p.CityTB).Count(o => o.CityTB.label == g.Key),
cases = db.Cases.Join(db.CourtSessions, u => u.ID, ui => ui.iDCase, (u, ui) => new { u, ui }).Count(m => m.ui.CityTB.label == g.Key)
});
Where CityTB is a foreign key
Cases (ID ...)
Cities (ID, Label)
CourtSession (ID, iDCase, iDCity ... CasesTB, CityTB)
I am getting this exception
base {System.Exception} = {"LINQ to Entities does not recognize the method 'System.Linq.IQueryable1[LawbookMVC.Models.CourtSession] Include[CourtSession,City](System.Linq.IQueryable1[LawbookMVC.Models.CourtSession], System.Linq.Expressions.Expression1[System.Func2[LawbookMVC.Mod...
Thanks.
Well i solved it, thanks you all
var dat = db.Cities
.GroupBy(a => new { a.label, a.ID})
.Select(g => new
{
city = g.Key.label,
sessions = db.CourtSessions.Count(o => o.iDCity == g.Key.ID),//,
cases = db.Cases.Join(db.CourtSessions, u => u.ID, ui => ui.iDCase, (u, ui) => new { u, ui }).Count(m => m.ui.CityTB.label == g.Key.label)
});

lambda expression join multiple tables with select and where clause

I have three table many to many relationship I have joined the three table and select the value I want but now I need to select one row from the query result by where by specifying the id this is my three table
And this is the query using LINQ lambda expression :
DataBaseContext db = new DataBaseContext();
public ActionResult Index()
{
var UserInRole = db.UserProfiles.
Join(db.UsersInRoles, u => u.UserId, uir => uir.UserId,
(u, uir) => new { u, uir }).
Join(db.Roles, r => r.uir.RoleId, ro => ro.RoleId, (r, ro) => new { r, ro })
.Select(m => new AddUserToRole
{
UserName = m.r.u.UserName,
RoleName = m.ro.RoleName
});
return View(UserInRole.ToList());
}
the result will be like that using sql query
sql query
select *
from UserProfile u join webpages_UsersInRoles uir on u.UserId = uir.UserId
join webpages_Roles r on uir.RoleId = r.RoleId
result of the sql query
now i use anther sql query to filter the result of previews sql query by where and set the condition to where u.UserId = 1 to only give me back the user with the id 1 like that
select *
from UserProfile u join webpages_UsersInRoles uir on u.UserId = uir.UserId
join webpages_Roles r on uir.RoleId = r.RoleId
where u.UserId = 1
and the result of this sql query
so how can i add the where clause to my lambda expression to give me the same result as the result of the sql query and thanks for any help
If I understand your questions correctly, all you need to do is add the .Where(m => m.r.u.UserId == 1):
var userInRole = db.UserProfiles.
Join(db.UsersInRoles, u => u.UserId, uir => uir.UserId,
(u, uir) => new { u, uir }).
Join(db.Roles, r => r.uir.RoleId, ro => ro.RoleId, (r, ro) => new { r, ro })
.Where(m => m.r.u.UserId == 1)
.Select (m => new AddUserToRole
{
UserName = m.r.u.UserName,
RoleName = m.ro.RoleName
});
Hope that helps.
I was looking for something and I found this post. I post this code that managed many-to-many relationships in case someone needs it.
var userInRole = db.UsersInRoles.Include(u => u.UserProfile).Include(u => u.Roles)
.Select (m => new
{
UserName = u.UserProfile.UserName,
RoleName = u.Roles.RoleName
});

Categories

Resources