Distinct with joins - entity-framework

How do I get distinct rows based on the Last_Name field when my format is as follows:
public ActionResult Index()
{
ResumeDbEntities srd = new ResumeDbEntities();
List<M_Employees> First_Name = srd.M_Employees.ToList();
List<M_Employees> Last_Name = srd.M_Employees.ToList();
List<M_Employees> CurrentLaborCategory = srd.M_Employees.ToList();
List<M_Offices> Location_Number = srd.M_Offices.ToList();
List<M_Offices> City = srd.M_Offices.ToList();
List<M_Offices> State = srd.M_Offices.ToList();
List<S_Emp_Resume> Resume_Name = srd.S_Emp_Resume.ToList();
var multipleTbl = (from p in Resume_Name
join t in Last_Name on p.Employee_Rec_Key equals t.Employee_Rec_Key
join o in Location_Number on t.Office_Rec_Key equals o.Office_Rec_Key
where t.Employee_Rec_Key == 3633
select new MultipleClassRes { M_Employeesdetails = t, S_Emp_Resumedetails = p, M_Officesdetails = o});
return View(multipleTbl);
}

Newly working with MVC but included the auto number from one of the joins.

Related

How to do this query using Django orm?

I have a Profile model and Complain model both are connected to the inbuilt User model.I have to do a query using both in which Profile model have residence. I want to have a count, that how many complains are made from a particular residence. I can do it using SQL but I didn't know how to do it using Django.
SELECT users_profile.residence,count(user_id)from users_profile INNER JOIN chp_complain on(users_profile.user_id = chp_complain.complain_user_id)GROUP BY(user_id)
Complain Model:-
class Complain(models.Model):
complain_user = models.ForeignKey(User, on_delete=models.CASCADE)
complain_department=models.CharField(max_length=100)
complain_subject = models.CharField(max_length = 100,help_text = "Enter the complain subject")
department_head=models.CharField(max_length=100)
recepient=models.CharField(max_length=100)
complain_description=models.TextField(max_length=2000)
date_posted = models.DateTimeField(default = timezone.now)
NOT_VISITED = 'NV'
VISITED = 'V'
INPROCESS = 'IP'
COMPLETED = 'C'
status = (
(NOT_VISITED, 'NV'),
(VISITED, 'V'),
(INPROCESS, 'IP'),
(COMPLETED, 'C'),)
status=models.CharField(max_length=2,choices=status,)
Profile Model:-
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
UID =models.CharField(max_length=30,default = "000",help_text = "'Staff's fill their STAFF ID and student's fill their ROLL NO " )
MALE = 'M'
FEMALE = 'F'
Gender=((MALE, 'Male'),(FEMALE, 'Female'),)
Gender=models.CharField(max_length=6,choices=Gender,default=MALE,)
FIRST = '1st'
SECOND = '2nd'
THIRD = '3rd'
FOURTH = '4th'
NGH = 'NGH'
NON_HOSTELER = 'Non_hosteler'
TEACHER_QUARTER = 'Teacher_quarter'
residence = ((FIRST, 'First'),(SECOND, 'Second'),(THIRD, 'Third'),(FOURTH, 'Fourth'),(NGH,'NGH'),(NON_HOSTELER, 'Non_hosteler'),(TEACHER_QUARTER,'Teacher_quarter'))
residence = models.CharField(max_length=20,choices=residence,default=FIRST,)
room_no=models.CharField(max_length=10,default = "000")
I want to have a count, that how many complains are made from a particular residence you can write:
Complain.objects.values('complain_user__profile__residence').annotate(complains_count=Count('id'))
In your SQL query:
SELECT users_profile.residence,count(user_id)from users_profile INNER JOIN chp_complain on(users_profile.user_id = chp_complain.complain_user_id)GROUP BY(user_id)
You calculate how many users filed complaints from a particular residence. It can be calculated as follows:
User.objects.values('profile__residence').annotate(Count('id'))

How should I get distinct Record in linq query

Hi I have tried below query to get the distinct record but I am not able to get the distinct record from below query.
var query = (from sr in db.StudentRequests
join r in db.Registrations on sr.RegistrationId equals r.RegistrationId
join cc in db.Campus on r.CampusId equals cc.CampusId
join c in db.Classes on sr.ClassId equals c.ClassId
from tc in db.TutorClasses.Where(t => t.ClassId == sr.ClassId).DefaultIfEmpty()
from srt in db.StudentRequestTimings.Where(s => s.StudentRequestId == sr.StudentRequestId).DefaultIfEmpty()
from tsr in db.TutorStudentRequests.Where(t => t.StudentRequestId == srt.StudentRequestId && t.TutorId == registrationid).DefaultIfEmpty()
where tc.RegistrationId == registrationid
select new
{
StudentRequestId = sr.StudentRequestId,
RegistrationId = sr.RegistrationId,
Location = sr.Location,
PaymentMethod = sr.PaymentMethod,
CreatedOn = sr.CreatedOn,
ClassName = c.ClassName,
CampusName = cc.CampusName,
StatusId = tsr.StatusId == null ? 1 : tsr.StatusId,
Time = db.StudentRequestTimings.Where(p => p.StudentRequestId == sr.StudentRequestId)
.Select(p => p.FromTime.ToString().Replace("AM", "").Replace("PM", "") + "-" + p.ToTime)
}).Distinct().ToList().ToPagedList(page ?? 1, 3);
But I am getting error as
The 'Distinct' operation cannot be applied to the collection
ResultType of the specified argument.\r\nParameter name: argument
So I had removed the .Distinct() from the above query and below that code I had written code as
query = query.Distinct().ToList();
But still the duplicate record was showing
So I had tried Group by clause to get distinct record but over there also I am facing the issue.Please Review below code
query = query.ToList().GroupBy(x => new { x.StudentRequestId, x.StatusId, x.Location, x.RegistrationId, x.PaymentMethod, x.CreatedOn, x.ClassName, x.CampusName})
.Select(group => new
{
StudentRequestId = group.Key.StudentRequestId,
StatusId = group.Key.StatusId,
Location = group.Key.Location,
RegistrationId = group.Key.RegistrationId,
PaymentMethod = group.Key.PaymentMethod,
CreatedOn = group.Key.CreatedOn,
ClassName = group.Key.ClassName,
CampusName = group.Key.CampusName,
Time1 = group.Key.Time
});
But I am getting error for time as
How can I get the distinct Value?
Also make in concern that I am using ToPagedList in the query
The actual issue is coming from Time column, If I remove that column all things are working fine.
I had added Group by clause at the end of the query as suggested by #Rajaji and that worked for me.
var query = (from sr in db.StudentRequests
join r in db.Registrations on sr.RegistrationId equals r.RegistrationId
join cc in db.Campus on r.CampusId equals cc.CampusId
join c in db.Classes on sr.ClassId equals c.ClassId
from tc in db.TutorClasses.Where(t => t.ClassId == sr.ClassId).DefaultIfEmpty()
from srt in db.StudentRequestTimings.Where(s => s.StudentRequestId == sr.StudentRequestId).DefaultIfEmpty()
from tsr in db.TutorStudentRequests.Where(t => t.StudentRequestId == srt.StudentRequestId && t.TutorId == registrationid).DefaultIfEmpty()
where tc.RegistrationId == registrationid
select new
{
StudentRequestId = sr.StudentRequestId,
RegistrationId = sr.RegistrationId,
Location = sr.Location,
PaymentMethod = sr.PaymentMethod,
CreatedOn = sr.CreatedOn,
ClassName = c.ClassName,
CampusName = cc.CampusName,
StatusId = tsr.StatusId == null ? 1 : tsr.StatusId,
Time = db.StudentRequestTimings.Where(p => p.StudentRequestId == sr.StudentRequestId).Select(p => p.FromTime.ToString().Replace("AM", "").Replace("PM", "") + "-" + p.ToTime)
}).ToList().GroupBy(p => new { p.StudentRequestId }).Select(g => g.First()).ToList();

How to improve query with two contexts - MVC5, LINQ n EF

I have two contexts. In one of them i have two views of which i get cods related to an entity from the another context. This query is taking too long time. How to improve it?
var negociacoes = _db.Negociacoes.Include(o=> o.User).ToArray();
var produtos = _oriDb.Vw_Produtos.ToArray();
var clientesVendedor = _oriDb.Vw_ClientesVendedores.ToArray();
var query = from n in negociacoes
join p in produtos on n.ProdutoId equals p.ProdutoId
join c in clientesVendedor on n.ClienteId equals c.codigo_entidade
select new NegociacaoView
{
NegociacaoId = n.NegociacaoId,
ProdutoId = n.ProdutoId,
Produto = p.descricao,
ClienteId = n.ClienteId,
Cliente = c.razao_social,
Rca = n.Rca,
Quantidade = n.Quantidade,
Preco = n.Preco,
Situacao = n.Situacao,
UserId = n.User.UserName,
Atendente = n.Atendente,
CondicaoId = n.CondicaoId,
DataCriacao = n.DataCriacao,
DataLiberacao = n.DataLiberacao,
Observacao = n.Observacao,
User = n.User
};
return query.ToList();
There are a couple of ways to speed this up:
It helps to run the smallest most efficient query first, then use those results to constrain the following queries.
Defining a select list so the database doesn't have to materialize every column will speed things up and use less memory.
Unfortunately, no matter how you do it in LINQ, you will end up with sql that uses large IN statements. A sproc would give you access to temp tables and joins that would be even better.
var negociacoes = _db.Negociacoes.Include(o=> o.User).ToArray();
//Use results of first query to constrain the second two. You could maybe combine the second two into one query.
var clientIds = negociacoes.Select(x => x.ClienteId);
var productIds = negociacoes.Select(x => x.ProdutoId);
var produtos = _oriDb.Vw_Produtos
.Where(x => productIds.Contains(x.ProdutoId))
//add a select. You're only using two columns from this table.
//.Select(x => new { })
.ToArray();
var clientesVendedor = _oriDb.Vw_ClientesVendedores
.Where(x => clientIds.Contains(x.codigo_entidade))
//add a select. You're only using two columns from this table.
//.Select(x => new { })
.ToArray();
var query = from n in negociacoes
join p in produtos on n.ProdutoId equals p.ProdutoId
join c in clientesVendedor on n.ClienteId equals c.codigo_entidade
select new NegociacaoView
{
NegociacaoId = n.NegociacaoId,
ProdutoId = n.ProdutoId,
Produto = p.descricao,
ClienteId = n.ClienteId,
Cliente = c.razao_social,
Rca = n.Rca,
Quantidade = n.Quantidade,
Preco = n.Preco,
Situacao = n.Situacao,
UserId = n.User.UserName,
Atendente = n.Atendente,
CondicaoId = n.CondicaoId,
DataCriacao = n.DataCriacao,
DataLiberacao = n.DataLiberacao,
Observacao = n.Observacao,
User = n.User
};
return query.ToList();

EF Append to an IQueryable a Where that generates an OR

I'm trying to achieve dynamic filtering on a table. My UI has filters that can be enabled or disabled on demand, and as you can imagine, my query should be able to know when to add filters to the query.
What I have so far is that I check if the filter object has a value, and if it does it adds a where clause to it. Example:
var q1 = DBContext.Table1
if (!string.IsNullOrEmpty(filterModel.SubjectContains))
q1 = q1.Where(i => i.Subject.Contains(filterModel.SubjectContains));
if (filterModel.EnvironmentId != null)
q1 = q1.Where(i => i.EnvironmentId == filterModel.EnvironmentId);
if (filterModel.CreatedBy != null)
q1 = q1.Where(i => i.CreatedByUserId == filterModel.CreatedBy);
var final = q1.Select(i => new
{
IssuesId = i.IssuesId,
Subject = i.Subject,
EnvironmentId = i.EnvironmentId,
CreatedBy = i.CreatedByUser.FullName,
});
return final.ToList();
The code above generates T-SQL that contains a WHERE clause for each field that uses AND to combine the conditions. This is fine, and will work for most cases.
Something like:
Select
IssueId, Subject, EnvironmentId, CreatedById
From
Table1
Where
(Subject like '%stackoverflow%')
and (EnvironmentId = 1)
and (CreatedById = 123)
But then I have a filter that explicitly needs an IssueId. I'm trying to figure out how the EF Where clause can generate an OR for me. I'm looking something that should generate a Tsql that looks like this:
Select
IssueId, Subject, EnvironmentId, CreatedById
From
Table1
Where
(Subject like '%stackoverflow%')
and (EnvironmentId = 1)
and (CreatedById = 123)
or (IssueId = 10001)
Found a solution for this that doesn't have to do multiple database call and works for me.
//filterModel.StaticIssueIds is of type List<Int32>
if (filterModel.StaticIssueIds != null)
{
//Get all ids declared in filterModel.StaticIssueIds
var qStaticIssues = DBContext.Table1.Where(i => filterModel.StaticIssueIds.Contains(i.IssuesId));
//Let's get all Issues that isn't declared in filterModel.StaticIssueIds from the original IQueryable
//we have to do this to ensure that there isn't any duplicate records.
q1 = q1.Where(i => !filterModel.StaticIssueIds.Contains(i.IssuesId));
//We then concatenate q1 and the qStaticIssues.
q1 = q1.Concat(qStaticIssues);
}
var final = q1.Select(i => new
{
IssuesId = i.IssuesId,
Subject = i.Subject,
EnvironmentId = i.EnvironmentId,
CreatedBy = i.CreatedByUser.FullName,
});
return final.ToList();

How to search multi keywork in linq query

i have this code in homepage
CheckBox[] ch= new CheckBox[12];
ch[0] = ChkContextA;
ch[1]= ChkContextB;
ch[2]= ChkContextC;
ch[3]= ChkContextD;
ch[4]= ChkContextE;
ch[5]= ChkContextF;
ch[6]= ChkContextG;
ch[7]= ChkContextH;
ch[8]= ChkContextI;
ch[9]= ChkContextJ;
ch[10]= ChkContextK;
ch[11]= ChiContextL;
for (int i = 0; i < 11; i++)
if (ch[i].Checked) search += ch[i].Text + " ";
Response.Redirect("SearchEstate.aspx?content="+search);
and this code in SearchEstate
var content = Request.QueryString["content"];
RealEstateEntities db = new RealEstateEntities();
var query = from O in db.Owners
join E in db.Estates on O.OwnerID equals E.OwnerID
join P in db.Properties on E.PropertyID equals P.PropertyID
where P.Facilities.Contains(content)
select new
{
regdate = E.RegisterDate,
region = E.Region,
Estype = E.EstateType,
Fac = P.Facilities,
deal = P.DealType,
price = P.TotalCost,
img = E.Picture,
addrss = O.Address,
area = P.Area,
tel = P.TellNum,
bed = P.RoomNum,
park = P.ParikingNum
};
Repeater2.DataSource = query.OrderByDescending(x => x.regdate);
Repeater2.DataBind();
when user checked some checkbox "content" for example have this value:
SearchEstate.aspx?content=ContextB ContextE ContextJ
I Want search this values in Facility field in db
How can I do this? (Sorry for my bad English)
I have the feeling your are looking for something along the lines of this query:
var content = Request.QueryString["content"];
string[] contentArray = content.Split(' ');
//...
var query = //...
where P.Facilities.Any(f => contentArray.Contains(f.FacilityName))
//...
(or instead of FacilityName some other property of Facility)
But I am not sure.