Linq query Left Join condition - linq

I'm trying to recreate the following sql query using Linq syntax, for some reason it is not working, please let me know what am I doing wrong here
My sql query:
select
cf.VisitConfigId,
cf.VisitName,
sv.VisitDate
from SubjectVisitConfig cf
left join SubjectVisit sv on cf.VisitConfigId = sv.VisitConfigId
My Linq query:
var q = from cf in ctms.SubjectVisitConfigs
join sv in ctms.SubjectVisits on cf.VisitConfigId equals
sv.VisitConfigId into JoinedVisits
from sv in JoinedVisits.DefaultIfEmpty()
where sv.SubjectId == subjectId.Value && sv.SiteId == siteId.Value
select new
{
sv.VisitId,
VisitDate = sv.VisitDate != null ? sv.VisitDate : null,
cf.VisitName
};
Thanks for your help!

You're dereferencing sv unconditionally in your select clause - but sv will be logically null for items which don't have a matching SubjectVisit. How would you expect your where clause to match any result where sv is null?
Here's one possible rewrite:
var q = from cf in ctms.SubjectVisitConfigs
join sv in ctms.SubjectVisits
.Where(x => x.SubjectId == subjectId.Value &&
x.SiteId == siteId.Value)
on cf.VisitConfigId equals sv.VisitConfigId into JoinedVisits
from sv in JoinedVisits.DefaultIfEmpty()
select new
{
VisitId = sv == null ? null : sv.VisitId,
VisitDate = sv == null ? null : sv.VisitDate,
cf.VisitName
};

Related

Linq query - ON clause of inner join cannot compare two Guids

If the person you are searching is a CIA emplyee, take his CIAJobs.EmployerID, otherwise select People.ID
SELECT
case when CIAJobs.EmployeeID IS NULL then People.ID
else CIAJobs.EmployerID
end
FROM [FMO].[People] AS p
LEFT JOIN [FMO].[CIAJobs] j
ON (p.ID = j.[EmployeeID])
AND (j.[relationshipType] = '25a8d79d-377e-4108-8c92-0ef9a2e1ab63')
where p.ID = '1b66e032-94b2-e811-96e0-f48c508e38a2' // id of person you search for
OR
j.[EmployeeID] = '1b66e032-94b2-e811-96e0-f48c508e38a2' // id of person you search for
I tried doing this in Linq:
var a = from l in People
join x in CIAJobs
on l.Id equals x.EmployeeID && x.RelationshipTypeGuid equals Guid.Parse('25a8d79d-377e-4108-8c92-0ef9a2e1ab63')
into gcomplex
from xx in gcomplex.DefaultIfEmpty()
select (xx.EmployeeID == null) ? l.EmployeeId : x.EmployerID;
var b = a.ToList();
why does the query show an error because of this chunk: && x.RelationshipTypeGuid equals Guid.Parse('25a8d79d-377e-4108-8c92-0ef9a2e1ab63')
If I remove this part it shows no error.
Error is: operator && cannot be applied to operands of type Guid and Guid.
Can you help me correct the Linq query please logically and syntactically? Thank you.
You don't need join for multiple conditions in this scenario. Use this
var a = from l in People
join x in CIAJobs
.Where(z=>z.RelationshipTypeGuid
.Equals(Guid.Parse('25a8d79d-377e-4108-8c92-0ef9a2e1ab63')))
on l.Id equals x.EmployeeID
into gcomplex
from xx in gcomplex.DefaultIfEmpty()
select (xx.EmployeeID == null) ? l.EmployeeId : x.EmployerID;
var b = a.ToList();
But based on your problem statement this should do
var a = from l in People
join x in CIAJobs
on l.Id equals x.EmployeeID
into gcomplex
from xx in gcomplex.DefaultIfEmpty()
select (xx == null) ? l.EmployeeId : xx.EmployerID;
var b = a.ToList();

LINQ - count from select with join with no group by

Linq is brand new to me so I apologize if this is really stupid.
I am trying to get the count from a multi-table join with where clause, without group by. I've seen examples of group by and will resort to that if need be, but I am wondering if there is a way to avoid it. Is sql my query would look something like this;
SELECT Count(*)
FROM plans p
JOIN organizations o
ON p.org_id = o.org_id
AND o.deleted IS NULL
JOIN orgdata od
ON od.org_id = o.org_id
AND od.active = 1
JOIN orgsys os
ON os.sys_id = od.sys_id
AND os.deleted IS NULL
WHERE p.deleted IS NULL
AND os.name NOT IN ( 'xxxx', 'yyyy', 'zzzz' )
What's the best way to get this?
All you need is to call Count(). You're only counting the number of results. So something like:
var names = new[] { "xxxx", "yyyy", "zzzz" };
var query = from plan in db.Plans
where plan.Deleted == null
join organization in db.Organizations
on plan.OrganizationId equals organization.OrganizationId
where organization.Deleted == null
join orgData in db.OrganizationData
on organization.OrganizationId equals orgData.OrganizationId
where orgData.Active == 1
join os on db.OrganizationSystems
on orgData.SystemId equals os.SystemId
where os.Deleted == null &&
!names.Contains(os.Name)
select 1; // It doesn't matter what you select here
var count = query.Count();

Linq join statement

I am trying to select from multiple tables in an entity model. But there are two columns I would like to select and it's just not working out. The LINQ statement I have is:
var searchResult = from i in _imEntities.Issues
join dept in _imEntities.Departments
on i.Issued_to_dept equals dept.Dept_ID
where i.State == 1
select new {
i.ID_No,
i.Issue_Date,
Raised_By = dept.Dept_Name
.Where(i.Raised_by_Dept == dept.Dept_ID),
Issued_To = dept.Dept_Name
.Where(i.Issued_to_dept == dept.Dept_ID),
Details = i.Details
};
The column names are all correct, but I just can't get the dept_Names into the Raised_By and Issued_To fields. Is there another way to execute this?
Try this:
var query = from i in _imEntities.Issues
join dept_r in _imEntities.Departments
on i.Issued_to_dept equals dept_r.Dept_ID
join dept_i in _imEntities.Departments
on i.Issued_to_dept equals dept_i.Dept_ID
where i.State == 1
select new {
i.ID_No,
i.Issue_Date,
Raised_By = dept_r.Dept_Name,
Issued_To = dept_i.Dept_Name,
Details = i.Details
};
It's not clear what you are trying to achieve. But you definitely trying to apply where filter on single name string (also predicate syntax is not correct). Here is query which conditionally returns Dept_Name in Raised_By and Issued_To properties:
var query = from i in _imEntities.Issues
join dept in _imEntities.Departments
on i.Issued_to_dept equals dept.Dept_ID
where i.State == 1
select new {
i.ID_No,
i.Issue_Date,
Raised_By = (i.Raised_by_Dept == dept.Dept_ID) ? dept.Dept_Name : null,
Issued_To = (i.Issued_to_dept == dept.Dept_ID) ? dept.Dept_Name : null,
Details = i.Details
};

Subselect with LINQ

I want to do a subselect with LINQ
What I have, but incorrect
var diretores = from item in db.San_PropostaConversa
join sc in db.San_Credenciada
on (item.Credenciada_Id) equals sc.Credenciada_Id
join sp in db.San_Proposta
on (item.Proposta_Id) equals sp.Proposta_Id
join si in db.San_Imovel
on (sp.Imovel_Id) equals si.Imovel_Id
join su in db.San_Usuario
on (item.Usuario_Id) equals su.Usuario_Id
where item.Proposta_Id == proposta
orderby item.DataHora descending
select new
{
sc.Apelido,
su.NomeCompleto,
su.DescricaoCargo1,
item.Comentario,
item.DataHora,
sp.Imovel_Id,
CredenciadaCaptadora_Id = si.Credenciada_Id,
item.Credenciada_Id,
(from item2 in db.San_Usuario
where item2.Cargo_Id == 9
&& item2.Excluido == 0
&& item2.Credenciada_Id == item.Credenciada_Id
select item2.Email)
};
In my SELECT statement, I want to recover an email column following some conditions that are specified in my WHERE clause.
Error
Invalid anonymous type member declarator. Anonymous type members must
be declared with a member assignment, simple name or member access
You have 2 problems in your linq expression:
You need to assign the result of the subquery to a member of the new anonymous type.
I think you only want to select 1 email with your subquery, so you need to use Single()/SingleOrDefault() or First()/FirstOrDefault().
Try this:
var diretores = from item in db.San_PropostaConversa
join sc in db.San_Credenciada
on item.Credenciada_Id equals sc.Credenciada_Id
join sp in db.San_Proposta
on (item.Proposta_Id) equals sp.Proposta_Id
join si in db.San_Imovel
on sp.Imovel_Id equals si.Imovel_Id
join su in db.San_Usuario
on item.Usuario_Id equals su.Usuario_Id
where item.Proposta_Id == proposta
orderby item.DataHora descending
select new
{
Apelido = sc.Apelido,
NomeCompleto = su.NomeCompleto,
DescricaoCargo1 = su.DescricaoCargo1,
Comentario = item.Comentario,
DataHora = item.DataHora,
Imovel_Id = sp.Imovel_Id,
CredenciadaCaptadora_Id = si.Credenciada_Id,
Credenciada_Id = item.Credenciada_Id,
Email = (from item2 in db.San_Usuario
where item2.Cargo_Id == 9
&& item2.Excluido == 0
&& item2.Credenciada_Id == item.Credenciada_Id
select item2.Email).FirstOrDefault()
};
Mostly this error occurring for unavailable assigning variable,
please try this
it will help you
var diretores = from item in db.San_PropostaConversa
join sc in db.San_Credenciada
on (item.Credenciada_Id) equals sc.Credenciada_Id
join sp in db.San_Proposta
on (item.Proposta_Id) equals sp.Proposta_Id
join si in db.San_Imovel
on (sp.Imovel_Id) equals si.Imovel_Id
join su in db.San_Usuario
on (item.Usuario_Id) equals su.Usuario_Id
where item.Proposta_Id == proposta
orderby item.DataHora descending
select new
{
Apelido=sc.Apelido,
NomeCompleto=su.NomeCompleto,
DescricaoCargo1=su.DescricaoCargo1,
Comentario=item.Comentario,
DataHora=item.DataHora,
Imovel_Id=sp.Imovel_Id,
CredenciadaCaptadora_Id = si.Credenciada_Id,
Credenciada_Id= item.Credenciada_Id,
result= (from item2 in db.San_Usuario
where item2.Cargo_Id == 9
&& item2.Excluido == 0
&& item2.Credenciada_Id == item.Credenciada_Id
select item2.Email)
};

Use of where in multiple joins to remove rows - linq

I have a table of orders. the status is on the soilorders which is joined to the orders.
I only want to return orders where the joined soilorder does not have status "Removed".
I had thought that
join sso in db.SoilSamplingOrders on ord.order_id equals sso.order_id
where sso.status.Equals("Removed")!=true
but then no records are returned!
thanks for any help (query below)
var query =
from ord in db.Orders
join sso in db.SoilSamplingOrders on ord.order_id equals sso.order_id
where sso.status.Equals("Removed")!=true
join cust in db.Customers on ord.customer_id equals cust.customer_id
select new Listing
{
assigned_to = sso.assigned_to,
company = cust.company,
order_id = ord.order_id,
order_created = ord.order_created,
customer_id = ord.customer_id,
order_created_by_employ_id = ord.order_created_by_employ_id,
first_farm_on_order = (from f in db.SoilSamplingSubJobs
where f.order_id == ord.order_id
select new ListingSubJob { first_farm_on_order = f.farm }).
AsEnumerable().First().first_farm_on_order,
total_fields = (from f in db.SoilSamplingSubJobs
where f.order_id == ord.order_id
select new { f.sssj_id }).AsEnumerable().Count(),
total_area = (float?) (from f in db.SoilSamplingSubJobs
where f.order_id == ord.order_id && f.area_ha != null
select f.area_ha ).Sum() ?? 0 ,
total_area_ph_density = (float?)(from f in db.SoilSamplingSubJobs
where f.order_id == ord.order_id && f.ph != null
select f.ph).Sum() ?? 0,
};
DOH! Just as nature abhors a vacuum, anything Null cannot be included in the select. Added values to the status field and bom it works.

Resources