Several time, i need to get the name of user in AplicationUsers (aspnetusers). Like in Chamado model (table) i have a column Id_Agente (user). With a simple List, i will get something like:
"3q0aju9-9ijuso-9sodkci..."
public class Chamado
{
public int Id { get; set; }
public DateTime Abertura { get; set; }
public string Titulo { get; set; }
public string Descricao { get; set; }
public string Id_Agente { get; set; }
[NotMapped]
public String NomeAgente { get; set; }
}
To work around, I created a NotMapped field and filled it with a foreach:
using (IdentityContext id2 = new IdentityContext())
{
foreach (var item in historicos)
{
item.NomeAgente = id2.Users
.Where(u => u.Id == item.Id_Agente)
.Select(u => u.Nome).FirstOrDefault();
}
}
But now I need to group Chamados by Agente, and it's becoming more and more harder, to work around. I tried to make another notMapped on chamados model named Qtde, make a list and extract from that list but returned a error:
public List<PainelChamados> ListarOrdem()
{
using (SistemaContext db = new SistemaContext())
{
var chamados = db.Chamado
.Where(c => c.Situacao != Chamado.Esituacao.Concluido)
.GroupBy(c => c.Id_Agente)
.Select(c => new Chamado { Id_Agente = c.Key, Qtde = c.Count() });
using (IdentityContext id2 = new IdentityContext())
{
foreach (var item in chamados)
{
item.NomeAgente = id2.Users
.Where(u => u.Id == item.Id_Agente)
.Select(u => u.Nome).FirstOrDefault();
}
}
var query = chamados
.Select(c => new PainelChamados
{
Agente = c.NomeAgente,
Qtde = c.Qtde
});
return query.ToList();
}
}
Last, but not least, how could I just Include aspnetusers table like another regular table:
var query = db.Suporte_Projeto
.Include(l => l.Licenciado)
.Include(c => c.Condominio)
.Include(pr => pr.ProjetoProduto)
.Include(p => p.ProjetoAcesso);
Chart Data
Error
I did another work around! It's seems to be a good option while i cant join aspnetusers to my models table:
public List<PainelChamados> ListarOrdem()
{
using (SistemaContext db = new SistemaContext())
{
var query = db.Chamado
.Where(c => (c.Situacao != Chamado.Esituacao.Concluido && c.Id_Agente != null))
.GroupBy(e => new { e.Id_Agente})
.Select(lg => new PainelChamados
{
CodAgente = lg.Key.Id_Agente,
Qtde = lg.Count()
});
UsuarioData ud = new UsuarioData();
List<PainelChamados> Lista = new List<PainelChamados>();
foreach (var item in query)
{
Lista.Add(new PainelChamados
{
CodAgente = item.CodAgente,
Agente = item.CodAgente == null ? string.Empty : ud.GetAgenteId(item.CodAgente),
Qtde = item.Qtde
});
}
return Lista;
}
}
What do you think, is it the best way to work around? I could return the list i desired.
Chart With Agente Names
Related
I have a list of objects like this
public class MyList
{
public int recordNo { get; set; }
public bool IsValid { get; set; }
}
var result= (from pool in context.Table.Where(prdicate)
select new ResultEntity
{
guid = pool.guid,
isValid = myList.FirstOrDefault(no => no.guid == pool.guid).IsValid //It thorws an error here
}
the error is
System.NotSupportedException:
the error caused because IsValid assign
So I want to join the list with a table, to asssign some values on it. How can I do that?
Customer customerAlias = null;
Organization organizationAlias = null;
IList<Customer> customers = session.QueryOver(() => customerAlias)
.Left.JoinAlias(x => x.Organization, () => organizationAlias)
.Where(customer => customer.Name == "Customer Name")
.And(() => customerAlias.Age > 18)
.AndNot(() => organizationAlias.Name == "Forbidden Organization")
.List();
I have page where i display list of tasks (with Jquery DataTable) and i want display Employee name with count of thire tasks. for example:
Smith (2) | John (1) | Thomas (1)
Tables:
AssignName:
Tasks (AssignId as ForeignKey):
Here what i did :
Here i get List of tasks and select some properties:
var Taskslist = db.Tasks.Select(g => new ServicetasksVM.ItemGroup
{
OpgaveServicesId = g.Id,
Opgaver = g.Opgaver,
Opgaveid = g.Id,
Opretteaf = g.Opretteaf,
OpretteDato = g.OpretteDato,
}).AsEnumerable();
Her iterating over the results to get count each id:
foreach (var item in result)
{
var AssignCount = db.AssignName.Where(c => c.Id == item.Assingid)
.GroupBy(x => x.Name)
.Select(b => new ServicetasksVM.ItemGroup { Assingid = b.Count(), EmployeeNames= b.Key });
}
Put all code together (for simplicity i remove unneeded code):
public JsonResult ListofTasks() {
var Taskslist = db.Tasks.Select(g => new ServicetasksVM.ItemGroup
{
OpgaveServicesId = g.Id,
Opgaver = g.Opgaver,
Opgaveid = g.Id,
Opretteaf = g.Opretteaf,
OpretteDato = g.OpretteDato,
}).AsEnumerable();
var result = Taskslist.Skip(start).Take(length).ToList();
foreach (var item in result)
{
var AssignCount = db.AssignName.Where(c => c.Id == item.Assingid)
.GroupBy(x => x.Name)
.Select(b => new ServicetasksVM.ItemGroup { Assingid = b.Count(), EmployeeNames= b.Key });
}
JsonResult json = Json(new { data = result, draw = Request["draw"], recordsTotal = totalrows, recordsFiltered = totalrowsefterfiltering }, JsonRequestBehavior.AllowGet);
json.MaxJsonLength = int.MaxValue;
return json;
ViewModel:
public List<ItemGroup> ItemGroups { get; set; }
public class ItemGroup
{
public ItemGroup()
{
}
public int OpgaveServicesId { get; set; }
public string Opgaver { get; set; }
public string Opretteaf { get; set; }
public DateTime? OpretteDato { get; set; }
public int Opgaveid { get; set; }
public int OpgaveSmartid { get; set; }
public string Opgavestatus { get; set; }
public int? Assingid { get; set; }
public string EmployeeNames { get; set; }
}
In the end when I check the results both Assingid and EmployeeNames are null. Can anyone please help me :)
Scope of AssignCount variable is limited to foreach loop, that is the reason you are getting Assingid and EmployeeNames as a null at the end of program.
To fix this issue, store each AssignCount to the list, so that you can access all counts out of foreach loop
...
//Define list of List of ItemGroup, as AssignCount is of type List<ItemGroup>
List<List<ServicetasksVM.ItemGroup>> itemGroups = new List<List<ServicetasksVM.ItemGroup>>();
foreach (var item in result)
{
var AssignCount = db.AssignName.Where(c => c.Id == item.Assingid)
.GroupBy(x => x.Name)
.Select(b => new ServicetasksVM.ItemGroup { Assingid = b.Count(), EmployeeNames= b.Key })
.ToList(); //Convert To List
itemGroups.Add(AssignCount); //Add each `AssignCount` to itemGroups
}
//Now list of AssignCount(s) is(are) accessible outside foreach loop
...
Your for loop is doing the counting and assigning it to the variable AssignCount which only exists in the scope of the for loop. You need to capture that result in a variable that is outside the scope of the loop to pass that along to your view.
Something like:
var itemGroups = new List<ItemGroup>();
foreach (var item in result)
{
var AssignCount = db.AssignName.Where(c => c.Id == item.Assingid)
.GroupBy(x => x.Name)
.Select(b => new ServicetasksVM.ItemGroup { Assingid = b.Count(), EmployeeNames= b.Key });
itemGroups.Add(AssignCount);
}
variable AssignCount is local in the foreach loop. better create collection outside of the loop and keep on adding to it inside the loop.
I have models like below:
public class Rhistory
{
public User User { get; set; }
}
public class Vhistory
{
public User User { get; set; }
}
public class User
{
public string UserId { get; set; }
}
public class Info
{
public List<Rhistory> Rhistory { get; set; }
public List<Vhistory> Vhistory { get; set; }
}
I have List<Info> that contains List<Rhistory> and List<Vhistory>
From List<Info> I want to fetch all UserId into new string[], that are present in List<Rhistory> user object and List<Vhistory> user object.
I am doing something like below:
string[] rHistoryUserIds = Info
.Where(u => !Equals(u.Rhistory, null))
.SelectMany(v => v.Rhistory)
.Select(c => new string[] { c.User.UserId })
.SelectMany(m => m)
.Distinct().Where(x => !string.IsNullOrEmpty(x)).ToArray();
string[] vHistoryUserIds = Info
.Where(u => !Equals(u.Vhistory, null))
.SelectMany(v => v.Vhistory)
.Select(c => new string[] { c.User.UserId })
.SelectMany(m => m)
.Distinct().Where(x => !string.IsNullOrEmpty(x)).ToArray();
string[] userIds = rHistoryUserIds.Union(vHistoryUserIds).ToArray();
Can anyone please suggest me a shorter and faster way of doing this?
Thanks in advance!
You can directly select the subsets of userId in Rhistory and Vhistory into a anonymous class, then use union within select query. Finally use SelectMany to get the userId array.
//Get your info list into infos
var infos = GetInfos();
var result = infos.Select(x => new
{
RUserIds = x.Rhistory.Select(a => a?.User.UserId),
VUserIds = x.Vhistory.Select(a => a?.User.UserId),
}).Select(x => new
{
UserIds = x.RUserIds.Union(x.VUserIds)
}).SelectMany(x => x.UserIds).Where(x => x != null).ToArray();
This is how I optimized it thanks to all who gave suggestions.
var rUsers = Info.Where(c => c.Rhistory != null)
.SelectMany(cn => cn.Rhistory)
.Select(users => users?.User?.UserId)
.Where(u => !string.IsNullOrWhiteSpace(u))
.Distinct();
var vUsers = Info.Where(c => c.Vhistory != null)
.SelectMany(cn => cn.Vhistory)
.Select(users => users?.User?.UserId)
.Where(u => !string.IsNullOrWhiteSpace(u))
.Distinct();
var userIds = rUsers.Union(vUsers).ToArray();
Object
namespace Example
{
public class ContractorAddValue
{
public Member Member { get; set; }
public List<Addresses> Addresses { get; set; }
public ICommand AddAddress { get; set; }
}
public class Addresses
{
public MemberAddress MemberAddress { get; set; }
public ICommand EditAddress { get; set; }
}
}
Query
public ObservableCollection<ContractorAddValue> GetContractorsOrderByCity()
{
var allContractors = (from c in db.Member where c.IsContrator == true select c).ToList();
//var allContractors2 = db.Member .Include(c => c.MemberAddress).SelectMany(c => c.MemberAddress).OrderBy(c => c.City).Select(c => c.Member ).ToList();
//var allContractors = (from c in db.Member where c.IsContrator == true select c).OrderBy(c => c.MemberAddress.OrderBy(x => x.City)).ToList(); <= dosent work
var listContractorAddValue = new ObservableCollection<ContractorAddValue>();
foreach (var i in allContractors)
{
var adressList = db.MemberAddress.Where(x => x.MemberId == i.MemberId).OrderBy(x => x.City).ToList();
ContractorAddValue contractorAddValue = new ContractorAddValue();
contractorAddValue.Member = i;
contractorAddValue.AddAddress = new BaseCommand(() => ContractorsViewModel.SendAddress(i.MemberId ));
contractorAddValue.Addresses = new List<Addresses>();
foreach (var a in adressList)
{
Addresses memberAdress = new Addresses();
memberAdress.MemberAddress = a;
memberAdress.EditAddress = new BaseCommand(() => ContractorsViewModel.SendEditAddress(a.MemberAddressId , i.MemberId ));
contractorAddValue.Addresses.Add(memberAdress);
}
listContractorAddValue.Add(contractorAddValue);
}
return listContractorAddValue;
}
allContractors2 - the order by works, but I retrieve repeating Members. In this approach I tried to use .Distinct() after Select(c => c.Member) but it doesn't work (the whole query stops working).
My goal is to make an order by MemberAddress.City
Thanks in advance!
I think that this code will work but you need to redefine the Equals method of the ContractorAddValue class.
I added one if statement when you want to add contractorAddValue to the list. First you need to check if your list contains that object. If not you add the object to the list. If yes you need to find that object and merge its addresses list with addresses list from the object you want to add.
public ObservableCollection<ContractorAddValue> GetContractorsOrderByCity()
{
var allContractors = (from c in db.Member where c.IsContrator == true select c).ToList();
//var allContractors2 = db.Member .Include(c => c.MemberAddress).SelectMany(c => c.MemberAddress).OrderBy(c => c.City).Select(c => c.Member ).ToList();
//var allContractors = (from c in db.Member where c.IsContrator == true select c).OrderBy(c => c.MemberAddress.OrderBy(x => x.City)).ToList(); <= dosent work
var listContractorAddValue = new ObservableCollection<ContractorAddValue>();
foreach (var i in allContractors)
{
var adressList = db.MemberAddress.Where(x => x.MemberId == i.MemberId).OrderBy(x => x.City).ToList();
ContractorAddValue contractorAddValue = new ContractorAddValue();
contractorAddValue.Member = i;
contractorAddValue.AddAddress = new BaseCommand(() => ContractorsViewModel.SendAddress(i.MemberId ));
contractorAddValue.Addresses = new List<Addresses>();
foreach (var a in adressList)
{
Addresses memberAdress = new Addresses();
memberAdress.MemberAddress = a;
memberAdress.EditAddress = new BaseCommand(() => ContractorsViewModel.SendEditAddress(a.MemberAddressId , i.MemberId ));
contractorAddValue.Addresses.Add(memberAdress);
}
if(!listContractorAddValue.Contains(contractorAddValue)){
listContractorAddValue.Add(contractorAddValue);
} else {
var contAddValue = listContractorAddValue.First(l => l.Equals( contractorAddValue));
contAddValue.Addresses.AddRange(contractorAddValue.Addresses);
}
}
return listContractorAddValue;
}
I am a little bit stuck here.
I got a Database with tables for projects and versions of these projects:
public class Project
{
public int Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public List<ProjectVersion> Versions { get; set; } = new List<ProjectVersion>();
public Project() { }
}
and
public class ProjectVersion
{
public int Id { get; set; }
public string Version { get; set; }
public string Checksum { get; set; }
public string Description { get; set; }
public ICollection<EntryPoint> EntryPoints { get; set; } = new List<EntryPoint>();
public ICollection<System> Systems { get; set; } = new List<System>();
public ProjectVersion() { }
}
now I want to get a specific version of a project and some detailed information
public static Project GetVersionByProjectId( int projectId, string version )
{
using ( var ctx = new DatabaseContext() )
{
var query =
ctx.Projects
.Where(p => p.Id.Equals(projectId))
.Join(
ctx.Versions.Where( v => v.Version.Equals( version )),
p => p.Id,
v => v.ProjectId,
(p, v) => new Project
{
Name = p.Name,
Type = p.Type,
Id = p.Id,
Versions = new List<ProjectVersion>
{
new ProjectVersion
{
Checksum = v.Checksum,
Description = v.Description,
Version = v.Version ,
EntryPoints = new List<EntryPoint>(v.EntryPoints),
Systems = new List<System>(v.Systems)
}
}
}
)
.Select(x => x);
var result = query.ToList();
return result[0];
}
}
if I remove the whole
Versions = new List<ProjectVersion>
it works and I get the Project but not the Version. When I tried the LINQ in LINQPad I got following error:
Cannot create a query result of type 'System.Collections.Generic.List`1[UserQuery+ProjectVersion]'.
How can I get the Project with the requested Version?
UPDATE
thanks to the ideas of #RomanoZumbé and #Maritim I could solve it. Problem was different classes of the models.
using ( var ctx = new DatabaseContext() )
{
var query =
ctx.Projects
.Include(p => p.Versions)
.Where(p => p.Id.Equals(projectId))
.Select( p =>
new Project()
{
Id = p.Id,
Name = p.Name,
Type = p.Type,
Versions =
p.Versions
.Where( v => v.Version.Equals(version))
.Select( v =>
new ProjectVersion()
{
Checksum = v.Checksum,
Description = v.Description,
EntryPoints =
v.EntryPoints
.Select( e => new EntryPoint()
{
Call = e.Call,
Step = e.Step
})
.ToList()
})
.ToList()
})
.Select(x => x);
var result = query.ToList();
return result[0];
}
I don't know if I understood it correctly, and this is from top of my mind, but I think it would be easier if you used the Include(...) statement. And since you already included the project 'Versions' (which is equivalent to a JOIN statement in the database), you can do something like:
var query =
ctx.Projects
.Include(p => p.Versions)
.Where(p => p.Id.Equals(projectId))
.Select(
new Project
{
Name = p.Name,
Type = p.Type,
Id = p.Id,
Versions = p.Versions.Where(v => v.Version.Equals(version))
});
return query.FirstOrDefault();
I'm not entirely sure wether this is what you want to achieve, but maybe it helps.
var res = (from p in ctx.Projects
let v = ctx.Versions.FirstOrDefault(x => p.Versions.Any(v => v.Id == x.Id))
where p.Id == projectId
select new Project
{
Name = p.Name,
Type = p.Type,
Id = p.Id,
Versions = new List<ProjectVersion>()
{
new ProjectVersion
{
Checksum = v.Checksum,
Description = v.Description,
Version = v.Version ,
EntryPoints = new List<EntryPoint>(v.EntryPoints),
Systems = new List<System>(v.Systems)
}
}
});
return res.FirstOrDefault()