LINQ with Subquery and left join - linq

I am trying to write LINQ query to generate below SQL query. I know it looks like assignment, but tried few syntax which generated wrong query.
select pm.Profile_Number,PD.Line_Abbrev,PD.Group_Code from Profile_Detail PD
INNER JOIN Profile_Master PM ON pd.profile_id = pm.profile_id
LEFT JOIN
(
SELECT Field_Abbr,Group_Code FROM vw_Group_Code
where ((US=1 AND Group_US_Obsolete <> 1) OR (CA=1 AND Group_CA_Obsolete <> 1) OR (MX=1 AND Group_MX_Obsolete <> 1))
)gcv ON PD.Line_Abbrev = gcv.Field_Abbr AND PD.Group_Code = gcv.Group_Code
WHERE PD.Profile_Id IN(42) AND gcv.Field_Abbr IS NULL
Tried version :
(from pd in _context.ProfileDetail
join pm in _context.ProfileMaster on pd.ProfileId equals pm.ProfileId
join vla in _context.VwLineAbbrvs on pd.LineAbbrev equals vla.LineAbbrev into gc
from vla in gc.DefaultIfEmpty()
where profileNumber.Contains(pd.ProfileId.ToString()) &&
((vla.IsUS && vla.USObsolete) || (vla.IsCA && !vla.CAObsolete) || (vla.IsMX && !vla.MXObsolete))
select new ObsoleteLineDetail
{
LineAbbrv = pd.LineAbbrev,
GroupCode = pd.GroupCode,
ProfileNumber = pm.ProfileNumber
}).ToList();

Related

Linq how to join tables with a where clause on each table and a count

The following LINQ query isn't allowed when I use multiple where elements - it stops liking the 'into':
var query =
from ph in _db.PlayHits
join ua in _db.UserAgents on ph.UserAgentId equals ua.UserAgentId
where (ph.VideoId == 1 && ua.AgentString.Contains("test"))
into hits
select new
{
ResultCount = hits.Count()
};
Any idea why or how I amend this?
The equivilent sql I want is:
select count(*) as ResultCount
from Playhits ph
join UserAgents ua on ph.UserAgentId = ua.UserAgentId
where ph.VideoId = 1
and ua.AgentString like '%test%'
To my understanding, counting of the results can be done using the extension methond Count as follows.
var query =
from ph in _db.PlayHits
join ua in _db.UserAgents on ph.UserAgentId equals ua.UserAgentId
where (ph.VideoId == 1 && ua.AgentString.Contains("test"));
int Result = query.Count();

SQL to LINQ with JOIN and SubQuery

I have a query that I' struggling to convert to LINQ. I just can't get my head around the required nesting. Here's the query in SQL (just freehand typed):
SELECT V.* FROM V
INNER JOIN VE ON V.ID = VE.V_ID
WHERE VE.USER_ID != #USER_ID
AND V.MAX > (SELECT COUNT(ID) FROM VE
WHERE VE.V_ID = V.ID AND VE.STATUS = 'SELECTED')
The Closest I've come to is this:
var query = from vac in _database.Vacancies
join e in _database.VacancyEngagements
on vac.Id equals e.VacancyId into va
from v in va.DefaultIfEmpty()
where vac.MaxRecruiters > (from ve in _database.VacancyEngagements
where ve.VacancyId == v.Id && ve.Status == Enums.VacanyEngagementStatus.ENGAGED
select ve).Count()
...which correctly resolves the subquery from my SQL statement. But I want to further restrict the returned V rows to only those where the current user does not have a related VE row.
I've realised that the SQL in the question was misleading and whilst it led to technically correct answers, they weren't what I was after. That's my fault for not reviewing the SQL properly so I apologise to #Andy B and #Ivan Stoev for the misleading post. Here's the LINQ that solved the problem for me. As stated in the post I needed to show vacancy rows where no linked vacancyEngagement rows existed. The ! operator provides ability to specify this with a subquery.
var query = from vac in _database.Vacancies
where !_database.VacancyEngagements.Any(ve => (ve.VacancyId == vac.Id && ve.UserId == user.Id))
&& vac.MaxRecruiters > (from ve in _database.VacancyEngagements
where ve.VacancyId == vac.Id && ve.Status == Enums.VacanyEngagementStatus.ENGAGED
select ve).Count()
This should work:
var filterOutUser = <userId you want to filter out>;
var query = from vac in _database.Vacancies
join e in _database.VacancyEngagements
on vac.Id equals e.VacancyId
where (e.UserId != filterOutUser) && vac.MaxRecruiters > (from ve in _database.VacancyEngagements
where ve.VacancyId == vac.Id && ve.Status == Enums.VacanyEngagementStatus.ENGAGED
select ve).Count()
select vac;
I removed the join to VacancyEngagements but if you need columns from that table you can add it back in.

How to convert exists condition inside where clause in Linq

I want to add following where clause to Linq query. How subquery like below using linq
WHERE (Restaurants.[IsActive] = 1)
AND exists
(
select 1 from APIKeys
where ApiKey = 'on35e5xbt3m4cbcef4e4448t6wssg11o'
and (KeyType = 1
and fk_RestaurantsID = [t2].[RestaurantsID]
or KeyType = 2
and fk_RestaurantGroupID = RG.RestaurantGroupsID
and [t1].[fk_RestaurantsID] in
(SELECT RestaurantsID
FROM Restaurants
WHERE RestaurantGroupsID = RG.RestaurantGroupsID))
)
AND (0 = (COALESCE([t0].[fk_MembersID],0)))
AND (1 = [t0].[fk_BookingStatusID])
AND ([t0].[Email] = 'nike.s#gmail.com')
AND (([t0].[Phone] = '9999999990') OR ([t0].[MobilePhone] = '9999999990'))
Use Any() to produce subquery which translated to EXISTS. E.g. with AdventureWorks database sample:
from p in Products
where p.FinishedGoodsFlag &&
SalesOrderDetails.Any(od => od.ProductID == p.ProductID)
select new { p.ProductID, p.Name }
Will produce following query to database:
SELECT [t0].[ProductID], [t0].[Name]
FROM [Production].[Product] AS [t0]
WHERE ([t0].[FinishedGoodsFlag] = 1) AND (EXISTS(
SELECT NULL AS [EMPTY]
FROM [Sales].[SalesOrderDetail] AS [t1]
WHERE [t1].[ProductID] = [t0].[ProductID]
))

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)
};

How to write Count, Distinct in LINQ from Oracle

I have a query in Oracle which i am trying to convert into linq. I think I am almost there. Here is the query in Oracle. I had quick problem with left outer joins in the query. Please consider this too in the question. My main problem is I can't write using this count, distinct for different columns in the table.
SELECT COUNT(DISTINCT claimant_id || rqst_wk_dt || claim_id) AS no_of_weeks_compensated
, SUM(pmt_am) AS total_payments
, COUNT(DISTINCT claimant_id || claim_id)
FROM (SELECT c.claimant_id
, c.claim_id
, c.rqst_wk_dt
, a.pmt_am
FROM ui_mon_hdr d
INNER JOIN ui_rqst_wk_ctrl c
ON d.claimant_id = c.claimant_id
AND d.claim_id = c.claim_id
LEFT OUTER JOIN ui_dstb_pmt a
ON c.claimant_id = a.claimant_id
AND c.claim_id = a.claim_id
AND c.rqst_wk_dt = a.rqst_wk_dt
AND a.rcpnt_id = 'CLMNT'
LEFT OUTER JOIN ui_claim_pmt b
ON c.claimant_id = b.claimant_id
AND c.claim_id = b.claim_id
AND warrant_dt BETWEEN '1 June 2011' AND '30 June 2011'
AND b.status_cd = 'PAID'
AND a.rcpnt_id = b.rcpnt_id --AND A.PMT_NU = B.PMT_NU
LEFT OUTER JOIN ui_auth_pmt e
ON c.claimant_id = e.claimant_id
AND c.claim_id = e.claimant_id
AND c.rqst_wk_dt = e.rqst_wk_dt
AND d.mon_seq_nu = e.mon_seq_nu
WHERE c.rqst_wk_dt BETWEEN '1 June 2011' AND '30 June 2011'
AND d.bspd_type_cd = 'ALTR')
Above is the query which I have in Oracle and run in TOAD. Below is the query in LINQ. I have just done internal select statement and I wonder how to implement the select count and distinct for the query:
var enddate = Convert.ToDateTime("6/30/2011");
var Altquery = from D in UiMonHdr
join C in UiRqstWkCtrl on new {D.ClaimantId, D.ClaimId} equals new {C.ClaimantId, C.ClaimId}
join A in UiDstbPmt on new {C.ClaimantId, C.ClaimId , C.RqstWkDt} equals new {A.ClaimantId, A.ClaimId, A.RqstWkDt}
where A.RcpntId.Contains("CLMNT")
join B in UiClaimPmt on new {C.ClaimantId, C.ClaimId, A.RcpntId} equals new {B.ClaimantId, B.ClaimId, B.RcpntId}
where B.StatusCd.Contains("PAID") && B.WarrantDt >= startdate && B.WarrantDt <= enddate
join E in UiAuthPmt on new {C.ClaimantId, C.ClaimId , C.RqstWkDt} equals new {E.ClaimantId, E.ClaimId, E.RqstWkDt}
where C.RqstWkDt >= startdate && C.RqstWkDt <= enddate && D.BspdTypeCd.Contains("ALTR")
select new {ClaimantId = C.ClaimantId, ClaimId = C.ClaimId, PmtAmt = A.PmtAm, RqstWkDt = C.RqstWkDt}; Altquery.Dump();

Resources