I have three database model which are shown below
I have two DTO class which are shown below
class RoleDTO
{
string RoleId;
string EnglishName;
Guid TypeId;
List<ClaimDTO> claims;
}
class ClaimDTO
{
string ActionID;
string ActionCode;
string ActionLevel;
string GrantDate;
}
Now I want to retrieve List of RoleDTO object from the database. So far I tried
public List<RoleDTO> GetRoleByType(Guid roleTypeId)
{
var roleDTOs = (from r in ctx.Roles
join rc in ctx.RoleClaims on r.RoleID equals rc.RoleID
join a in ctx.Actions on rc.ActionID equals a.ActionID
where r.RoleTypeID == roleTypeId
select new RoleDTO
{
RoleId = r.RoleID,
EnglishName = r.EnglishName,
TypeId = r.TypeID,
claims = List of ClaimDTO objects related to this role
}).ToList();
return roleDTOs;
}
My question is how can I retrieve list of ClaimDTO objects inside select statement. Is my linq correct?
I am using Telerik OpenAccess as ORM.
Below change should help to get the results
public List<RoleDTO> GetRoleByType(Guid roleTypeId)
{
var roleDTOs = (from r in ctx.Roles
join rc in ctx.RoleClaims on r.RoleID equals rc.RoleID
where r.RoleTypeID == roleTypeId
select new RoleDTO
{
RoleId = r.RoleID,
EnglishName = r.EnglishName,
TypeId = r.TypeID,
claims = ctx.Actions.Where( c => c.ActionId == rc.ActionId).Select( s => new ClaimDTO
{
ActionID = s.ActionID,
ActionCode = s.ActionCode,
ActionLevel = s.ActionLevel,
GrantDate = s.GrantDate
})ToList()
}).ToList();
return roleDTOs;
}
Another Alternative
List<ClaimDTO> claimsList = ctx.Actions.Select( s => new ClaimDTO
{
ActionID = s.ActionID,
ActionCode = s.ActionCode,
ActionLevel = s.ActionLevel,
GrantDate = s.GrantDate
})ToList();
var roleDTOs = ctx.Roles.Join(ctx.RoleClaims, r => r.RoleID, rc => rc.RoleID, (r,rc) => new
{
r,rc
}).Where( r => r.RoleTypeID == roleTypeId)
.Select( row => new RoleDTO
{
RoleID = row.r.RoleID,
EnglishName = row.r.EnglishName,
TypeID = row.r.TypeID,
claims = claimsList.Where( c => c.ActionId == rc.ActionId)
}).ToList();
If you use Include method then below query could help
var roleDTOs = ctx.Roles.Include("RoleClaims").Join(ctx.Actions, r => r.RoleClaims.Select(rc => rc.ActionID).FirstOrDefault() , a => a.actionid , (r,a) => new
{
r,a
}.Where(r => r.RoleTypeID == roleTypeId)
.Select( row => new RoleDTO
{
RoleID = row.r.RoleID,
EnglishName = row.r.EnglishName,
TypeId = row.r.RoleTypeID,
Claims = row.a.Select( c => new ClaimDTO
{
ActionID = c.ActionID,
ActionCode = c.ActionCode,
ActionLevel = c.ActionLabel,
GrantDate = row.r.RoleClaims.Select( g => g.grantDate)
})
}).ToList();
Related
I have a Linq Query that is working as intended, but I need to add the code so that it will show me ONLY the people with the less cases assigned for an app that is been used to treat customers inquiries. The idea behind the query is so that it will let me automatically assign inquiries randomly between those agents which have less assigned issues to cover.
As a simple example, lets say I have 5 agents with just 1 case each, I need to randomly assign one of them to an Inquire which has currently no agent assigned. So all I'm looking for is a way to actually get all the agents with the smallest number of cases assigned.
So far this is the full proof of concept code:
var inquires = new List<Inquire>();
var agents = new List<Agent>();
LoadData();
var assignationsPerAgent = (from agent in agents
join inq in inquires on agent equals inq.AssignedAgent into agentsInInquires
select new {
o_agent = agent,
casesAssignedTo = agentsInInquires.Count()
}).ToList();
//This works but is NOT the kind of solution I'm looking for
var min = assignationsPerAgent.Min(c => c.casesAsignedTo);
var agentWithMin = assignationsPerAgent.Where(a => a.casesAsignedTo == min);
Console.WriteLine();
void LoadData()
{
agents = new(){
new Agent{ Id = Guid.Parse("317d3d26-25c2-49da-aa4b-b7e49a1b9015"), Name = "Robert" },
new Agent{ Id = Guid.Parse("84188e21-8147-498f-bc2a-59874dc4a24a"), Name = "Corina" },
new Agent{ Id = Guid.Parse("90ca6658-95d4-4df4-a072-159087feddc0"), Name = "John" },
new Agent{ Id = Guid.Parse("34e091e4-cc7a-4222-9885-5de5bb5a0291"), Name = "Jack"},
new Agent{ Id = Guid.Parse("f22dcb4e-e927-4ddf-ae66-f37c0de6753d"), Name = "Samuel"}
};
inquires = new(){
new Inquire{ CustomerName = "Paula", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("317d3d26-25c2-49da-aa4b-b7e49a1b9015"))},
new Inquire{ CustomerName = "Barry", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("84188e21-8147-498f-bc2a-59874dc4a24a"))},
new Inquire{ CustomerName = "Bertie", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("84188e21-8147-498f-bc2a-59874dc4a24a"))},
new Inquire{ CustomerName = "Herman", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("90ca6658-95d4-4df4-a072-159087feddc0"))},
new Inquire{ CustomerName = "Ashley", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("317d3d26-25c2-49da-aa4b-b7e49a1b9015"))},
new Inquire{ CustomerName = "Tate", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("90ca6658-95d4-4df4-a072-159087feddc0"))},
new Inquire{ CustomerName = "Bonnie", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("90ca6658-95d4-4df4-a072-159087feddc0"))},
new Inquire{ CustomerName = "Tabitha", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("90ca6658-95d4-4df4-a072-159087feddc0"))},
new Inquire{ CustomerName = "Ashley", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("34e091e4-cc7a-4222-9885-5de5bb5a0291"))},
new Inquire{ CustomerName = "Josie", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("84188e21-8147-498f-bc2a-59874dc4a24a"))},
new Inquire{ CustomerName = "Kelly", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("84188e21-8147-498f-bc2a-59874dc4a24a"))},
new Inquire{ CustomerName = "Kelly", AsignedAgent = agents.Single(a => a.Id == Guid.Parse("f22dcb4e-e927-4ddf-ae66-f37c0de6753d"))},
};
}
#nullable disable
class Inquire
{
private Guid _id;
public Guid Id
{
get
{
return _id;
}
private set
{
_id = Guid.NewGuid();
}
}
public string CustomerName { get; set; }
public Agent AsignedAgent { get; set; }
}
#nullable disable
class Agent
{
public Guid Id {get; set;}
public string Name { get; set; }
}
Please take in consideration that the assignationsPerAgent variable is simulating data coming from a query in the database (The actual query is below). If the "easy" way to do this comes from the SQL that it's also an acceptable solution.
SELECT u.Id, COUNT(g.Id) as QtyAsig
FROM Users as u
LEFT JOIN GeneralInquires AS g ON u.Id = g.UserId
GROUP BY u.Id
ORDER BY COUNT(g.Id)
What I'm getting from this Query is:
Id QtyAsig
8A21A6D2-0CEC-4F5C-2A6B-08DA60967E94 1
323C8D1A-2FAE-4ECC-D7A2-08DA6098F19A 1
BA485F3C-C44A-4FE5-9BFA-08DA64EF283A 1
8F0E856E-FA0B-4167-BBEF-08DA6451FA81 2
40952727-5C76-4902-9C4F-08DA638B3068 3
DD51085A-5BE3-4872-F4B5-08DA6E7828AA 4
What I need is:
Id QtyAsig
8A21A6D2-0CEC-4F5C-2A6B-08DA60967E94 1
323C8D1A-2FAE-4ECC-D7A2-08DA6098F19A 1
BA485F3C-C44A-4FE5-9BFA-08DA64EF283A 1
Thank you in advance!
check this
var assignationsPerAgent = (from agent in agents
join inq in inquires on agent equals inq.AsignedAgent into agentsInInquires
from inq in agentsInInquires.DefaultIfEmpty()
select new
{
o_agent = agent,
casesAssignedTo = agentsInInquires.Count()
}).GroupBy(x=>x.casesAssignedTo).OrderBy(x=>x.Key).FirstOrDefault();
Linq doesn't require one statement and splitting results has no impact on performance. Try following :
List<Inquire> sortedInquires = inquires.OrderBy(x => x.AsignedAgent.Id).ToList();
var results = (from a in agents
//join i in sortedInquires on a.Id equals i.Id
join i in sortedInquires on a.Id equals i.AssignedAgent
select new { agent = a, inquires = i}
).GroupBy(x => x.agent.Id)
.Select(x => x.First())
.ToList();
I receive this error, and I tried a lot to solve it, but I receive other errors, is there a solution?
using (var contextDb1 = new Db1Context(System.Web.HttpContext.Current.Session["DB1ConnectionString"].ToString(), false))
{
using (var contextDb2 = new Db2Context(System.Web.HttpContext.Current.Session["DB2ConnectionString"].ToString(), false))
{
var messagesList = contextDb2.Messages
.Select(m => new MessagesViewModel
{
UserName = contextDb1.UsersInfo.FirstOrDefault(u=>u.Id == m.UserId).UserName,
MessageId = m.MessageId,
MessageText = m.MessageText,
DateTime = m.DateTime
})
.ToList();
return messagesList;
}
}
You cannot query two different databases via the same LINQ Query. But you can use intermediate result to execute two queries to databases and then combine result.
using (var contextDb1 = new Db1Context(System.Web.HttpContext.Current.Session["DB1ConnectionString"].ToString(), false))
using (var contextDb2 = new Db2Context(System.Web.HttpContext.Current.Session["DB2ConnectionString"].ToString(), false))
{
var rawMessages = contextDb2.Messages
.Select(m => new
{
m.UserId
m.MessageId,
m.MessageText,
m.DateTime
})
.ToList();
var userIds = rawMessages.Select(x => xu.UserId);
var usersInfo = contextDb1.UsersInfo.Where(u => userIds.Contains(u.Id))
.Select(u => new
{
UserId = u.Id,
UserName = u.UserName
});
var messageQuery =
from m in rawMessages
join u in usersInfo.AsEnumerable() on m.UserId equals u.UserId into gj
from u in gj.DefaultIfEmpty()
select new MessagesViewModel
{
UserName = u?.UserName,
MessageId = m.MessageId,
MessageText = m.MessageText,
DateTime = m.DateTime
};
var messagesList = messageQuery.ToList();
return messagesList;
}
I'm having trouble working with Entity Framework and PostgreSQL, does anybody know how to join two tables and use the second table as a where clause?
The select I want to do in Entity Framework would be in SQL:
SELECT ai.id, ai.title, ai.description, ai.coverimageurl
FROM app_information ai
INNER JOIN app_languages al on al.id = ai.languageid
WHERE al.languagecode = 'es'
Currently I have this
appInformationToReturn = context.app_information
.Join(context.app_language, ai => ai.languageid,
al => al.id, (ai, al) => new AppInformation()
{
id = ai.id,
title = ai.title,
description = ai.description,
coverimageurl = ai.coverimageurl
})
.Where()
.FirstOrDefault();
I don't know how to build the where clause.
Like this:
appInformationToReturn = context.app_information
.Join(context.app_language, ai => ai.languageid,
al => al.id, (ai, al) => new
{
id = ai.id,
title = ai.title,
description = ai.description,
coverimageurl = ai.coverimageurl,
lang = al.languagecode
}).Where(x=>x.lang == "es")
.Select(x=> new AppInformation()
{
id = x.id,
title = x.title,
description = x.description,
coverimageurl = x.coverimageurl
})
.FirstOrDefault();
try this:
var item = (
from ai in context.app_information
join al in context.app_language on ai.languageid equals al.id
where (al.languagecode == "es")
select new AppInformation
{
id = ai.id,
title = ai.title,
description = ai.description,
coverimageurl = ai.coverimageurl
}).FirstOrDefault();
or try shorter
var item = context.app_information
.Where(ai => ai.app_language.languagecode == "es")
.Select(ai => new AppInformation
{
id = ai.id,
title = ai.title,
description = ai.description,
coverimageurl = ai.coverimageurl
})
.FirstOrDefault();
I am trying to use LinQ to join a table itself, in order to display different columns in different session. In this case is when the LanguageId is "en" the "EnglishName" columns should be assigned to "Name". It always shows the error "cannot implicitly convert type...". I dont' know how to fix this code. Pls see the code bellow and help. Many tks.
MemberDao
public List<MemberViewModel> ListNewMember(int top, string languageId)
{
if (languageId == "en")
{
var model1 = from a in db.Members
join b in db.Members
on a.MemberId equals b.MemberId
select new MemberViewModel()
{
MemberId = a.MemberId,
Name = a.EnglishName,
Status = a.Status,
CreatedDate = a.CreatedDate
};
IQueryable<MemberViewModel> model2 = model1;
model2 = model2.Where(x => x.Status == true).OrderByDescending(x => x.CreatedDate).Take(top).ToList();
}
return db.Members.Where(x => x.Status == true).OrderByDescending(x => x.CreatedDate).Take(top).ToList();
}
MemberController
using GBVNET.Common;
using Model.Dao;
using Models.Dao;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace GBVNET.Controllers
{
public class MemberController : BaseClientController
{
//[ChildActionOnly]
//[OutputCache(Duration = 3600 * 24)]
public ActionResult Index()
{
var slideDao = new SlideDao();
var currentCulture = Session[CommonConstants.CurrentCulture].ToString();
ViewBag.ChildrenSlides = slideDao.ListChildrenSlide(1, currentCulture);
var categoryDao = new CategoryDao();
ViewBag.DocumentCategory = categoryDao.DocumentCategory(1, currentCulture);
ViewBag.ContactCategory = categoryDao.ContactCategory(1, currentCulture);
var model = new MemberDao().ListNewMember(5, currentCulture);
return View(model);
}
public ActionResult Detail(int id)
{
var slideDao = new SlideDao();
var currentCulture = Session[CommonConstants.CurrentCulture].ToString();
ViewBag.ChildrenSlides = slideDao.ListChildrenSlide(1, currentCulture);
var categoryDao = new CategoryDao();
ViewBag.DocumentCategory = categoryDao.DocumentCategory(1, currentCulture);
ViewBag.ContactCategory = categoryDao.ContactCategory(1, currentCulture);
var member = new MemberDao().ViewDetail(id);
return View(member);
}
}
}
This is the screenshot of the error: https://i.stack.imgur.com/q9qB2.jpg
I fixed them all by change the code as bellow:
MemberDao
public List<MemberViewModel> ListNewMember(int top, string languageId)
{
if (languageId == "en")
{
IEnumerable<MemberViewModel> model = from a in db.Members
join b in db.Members
on a.MemberId equals b.MemberId
select new MemberViewModel()
{
MemberId = a.MemberId,
Name = b.EnglishName,
Status = a.Status,
Logo = a.Logo,
Email = a.Email,
Address = a.Address,
Banner = a.Banner,
Facebook = a.Facebook,
Description = b.EnglishDescription
};
model = model.Where(x => x.Status == true).OrderByDescending(x => x.CreatedDate).Take(top).ToList();
return model.Where(x => x.Status == true).OrderByDescending(x => x.CreatedDate).Take(top).ToList();
}
else
{
IEnumerable<MemberViewModel> model = from a in db.Members
join b in db.Members
on a.MemberId equals b.MemberId
select new MemberViewModel()
{
MemberId = a.MemberId,
Name = b.Name,
Status = a.Status,
Logo = a.Logo,
Email = a.Email,
Address = a.Address,
Banner = a.Banner,
Facebook = a.Facebook,
Description = a.Description
};
model = model.Where(x => x.Status == true).OrderByDescending(x => x.CreatedDate).Take(top).ToList();
return model.Where(x => x.Status == true).OrderByDescending(x => x.CreatedDate).Take(top).ToList();
}
}
I have a linq query that returns users/employees with their corresponding supervisors.
List<OrgChartViewModel> OrgChart = new List<OrgChartViewModel>();
var userlist = (from u in users
select new OrgChartViewModel
{
id = u?.id.ToString(),
pid = u?.pid.ToString(),
name = u?.name,
title = u?.title,
img = u?.img
}).OrderBy(x => x.name).ToList();
OrgChart.AddRange(userlist);
return Json(OrgChart.DistinctBy(x => x.id));
However, I need a query that returns the supervisor and their children along with their sub-children without having a sub-array/nested array.
What I have tried :
List<OrgChartViewModel> OrgChart = new List<OrgChartViewModel>();
var userlist = (from u in users
select new OrgChartViewModel
{
id = u?.id.ToString(),
pid = u?.pid.ToString(),
name = u?.name,
title = u?.title,
img = u?.img
}).OrderBy(x => x.name).ToList();
OrgChart.AddRange(userlist);
foreach (var ul in userlist)
{
var userlist2 = (from u in users
select new OrgChartViewModel
{
id = u?.id.ToString(),
pid = u?.pid.ToString(),
name = u?.name,
title = u?.title,
img = u?.img
}).Where(x => x.pid == ul.id).OrderBy(x => x.name).ToList();
OrgChart.AddRange(userlist2);
}
return Json(OrgChart.DistinctBy(x => x.id));
But this only returns the first layer of sub-children. What I want to achieve is to return unlimited layers of sub-children without having sub-arrays.