I have a linq query where i'm trying to return data if the right Sales table doesn't have a record and also only if the Sales.Fallthrough == false && Sales.Date == null.
This is the base of my query and i've tried many different things with this but can't seem to get it to return the required data. Everything I try only seems to return records if there is no Sales OR they match the WERE caluse but not both.
from cr in efContext.Cases
join si in efContext.Sales on cr.CaseId equals si.CaseId into sicr
from sicr in (from si in sicr
where si == null
select si
).DefaultIfEmpty()
where cr.Withdrawn == false
select new
{
CaseId = cr.CaseId,
PropertyAddress = extension.PropertyAddressTownFormat(cr.PropertyAddress1, cr.PropertyTown),
TargetExchangeDate = sicr.TargetExchangeDate == null ? null : sicr1.TargetExchangeDate,
ActualExchangeDate = sicr.ActualExchangeDate,
}).ToList();
EDIT
Missed out a little information.
Also if there is a record in Sales but does not match WHERE clauses then still return the left side and the right side as if there wasn't a record.
Thanks.
Isn't it just...?
from cr in efContext.Cases
join si in efContext.Sales on cr.CaseId equals si.CaseId into sicr
from s in sicr.DefaultIfEmpty()
select new
{
CaseId = cr.CaseId,
PropertyAddress = extension.PropertyAddressTownFormat(cr.PropertyAddress1, cr.PropertyTown),
TargetExchangeDate = s == null || (s.Fallthrough == false && s.Date == null) ? null : s.TargetExchangeDate,
ActualExchangeDate = s == null || (s.Fallthrough == false && s.Date == null) ? null : s.ActualExchangeDate,
};
Please note that you cannot call to ToList since the query returns an anonymous type.
Related
I have two tables; EndToEnd and PartPort. I'd like to get the PartPortA and PartportB data from the same row in EndToEnd, and query Partport with them and get their corresponding PartGid from Partport which could be on any row in the Partport table. So far, I'm able to do this, but I have to do two different LINQ calls but I'd like to reduce it down to one. Here is my code:
// this demonstrates how to join two tables, however only works for one AssetportGid at a time
var part_portGid_a_results = (from icp in entities.EndToEnd
where icp.IntertPortGidA != null &&
icp.IntertPortGidB != null
join ica in entities.PartPort
on icp.PartPortA equals ica.PortGid
select new { icp.PartPortA, ica.PartGid, }).ToList();
var part_portGid_b_results = (from icp in entities.EndToEnd
where icp.IntertPortGidA != null &&
icp.IntertPortGidB != null
join ica in entities.PartPort
on icp.PartPortB equals ica.PortGid
select new { icp.PartPortA, ica.PartGid, }).ToList();
return Json(part_portGid_a_results, JsonRequestBehavior.AllowGet);
What i'd like to do, and I have already tried but got an error is this:
var part_portGid_a_results = (from icp in entities.EndToEnd
where icp.IntertPortGidA != null &&
icp.IntertPortGidB != null
join ica in entities.PartPort
on icp.PartPortA && icp.PartPortB equals ica.PortGid
select new { icp.PartPortA, ica.PartGid, }).ToList();
The error i get is:
Guid? EndToEnd.PartPortB
Error:
Operator '&&' cannot be applied to operands of type 'System.Guid' and 'System.Guid?'
You don't have to use join. If you want to join with a "complex" comparison, just make a Cartesian product (from ... from) and link the rows by a where clause
var part_portGid_results = (from icp in entities.EndToEnd
where icp.IntertPortGidA != null &&
icp.IntertPortGidB != null
from ica in entities.PartPort
where icp.PartPortA == ica.PortGid
|| icp.PartPortB == ica.PortGid
select new { icp.PartPortA, ica.PartGid, }).ToList();
This is the SQL query I have written:
select * from Addresses a
join ProviderAddresses pa on a.address_k = pa.address_k
where pa.provider_k = 'ABC123'
and pa.active = 1
and a.active = 1
and pa.addresstype_rtk = 'HOME'
And this is the LINQ query I wrote for it:
public IQueryable<Addresses> GetAddressesesForProvider(string provider_k, string addresstype_rtk)
{
var query = from a in this.Context.Addresses
join pa in this.Context.ProviderAddresses on a.Address_K equals pa.Address_K
where pa.AddressType_RTK == addresstype_rtk
&& pa.Active == true
&& a.Active == true
select a;
return query;
}
But it is wrong. The LINQ one return thousands of records and the SQL one returns only one record.
It is IQueryable because later I need to go through its results with a for-each loop.
In the SQL I am passing hard coded values for testing but in my code for me LINQ method I also pass the same hard coded values so that is not the issue.
Looks like you may have just missed adding the provider_k condition to the where;
public IQueryable<Addresses> GetAddressesesForProvider(string provider_k, string addresstype_rtk)
{
var query = from a in this.Context.Addresses
join pa in this.Context.ProviderAddresses on a.Address_K equals pa.Address_K
where pa.Provider_K == provider_k &&
pa.AddressType_RTK == addresstype_rtk &&
pa.Active == true &&
a.Active == true
select a;
return query;
}
I have a linq query which is pulling in the wrong results. My guess is that it's doing this because I'm missing a bracket or something or another.
var CurrentlyActiveIncidents = from b in db.Logs
join dc in db.Incidents
on b.LogID equals dc.LogID
where b.DateTimeResolved == null &&
(dc.AssignedTechnician != null ||
dc.AssignedTechnician != CurrentUser)
I want all the incidents where the datetimeresolved == null and the assigned technician isn't null or is not assigned to the current user. At the moment the query is ignoring the != currentuser part and I don't know why?
As you require all those records which has assigned technician != null and != current user
so you need to have And Condition
var CurrentlyActiveIncidents = from b in db.Logs
join dc in db.Incidents
on b.LogID equals dc.LogID
where b.DateTimeResolved == null &&
(dc.AssignedTechnician != null &&
dc.AssignedTechnician != CurrentUser)
this will give you required records
I have three Table One is "Allowance " ,"Balance" and "TimeoffRequests" in these three table common columns are EmployeeId and TimeoffTypeId, Now i need to get the requested hours of one leave type by grouping thier timeoffTypeId and EmployeeId from the table "TimeoffRequests" , and got the "TimeOffHours". for the i wrote the code like
var query = (from tr in TimeOffRequests
where tr.EmployeeID == 9
group tr by new { tr.EmployeeID, tr.TimeOffTypeID } into res
select new
{
EmployeeID = res.Key.EmployeeID,
TimeOffTypeID = res.Key.TimeOffTypeID,
TotalHours = res.Sum(x => x.TimeOffHours)
}).AsEnumerable();
Now I need to join these results with the first table and have to get the all the employees, and timeoffTypes from the UserAllowance and corresponding TimeoffHours from the grouped table. for getting left joined query i wrote like below.
var requestResult = (from UA in UserAllowances
join UB in UserBalances on UA.EmployeeID equals UB.EmployeeID
where UA.TimeOffTypeID == UB.TimeOffTypeID && UA.EmployeeID == 9
&& UA.TimeOffType.IsDeductableType == true // LeftJoin
join rest in query on UA.EmployeeID equals rest.EmployeeID into penidngRequst
from penReq in penidngRequst.DefaultIfEmpty()
where penReq.TimeOffTypeID == UA.TimeOffTypeID
select new EmployeeTimeOffBalanceModel
{
TimeOffTypeID = UA.TimeOffTypeID != null ? UA.TimeOffTypeID : 0,
YearlyAllowanceHrs = (UA.YearlyAllowanceHrs != null) ? UA.YearlyAllowanceHrs : 0,
BalanceHours = UB.BalanceHrs != null ? UB.BalanceHrs : 0,
PendingHours = (decimal)((penReq != null) ? (penReq.TotalHours) : 0),
EmployeeID = UA != null ? UA.EmployeeID : 0,
}).ToList().Distinct();
It is giving only timeOFfType containing in grouped data,even though I wrote leftjoin for the query using the "into" and DefaultIfEmpty() keywords. the results becomes as like:
and by using the "linqPad" editor i found that it is applying the Cross or Outer Join instead of "left join" what will be the reason.
If I remove this line of code " where penReq.TimeOffTypeID
== UA.TimeOffTypeID" this showing all the timeoffTypes with cross join with repeatation like
How can I achieve left join with tables with Grouped data and showing null values if timeofftypes didn't having the any request?
You might want to move the where clause into the the on equals clause as shown below
join rest in query on new { UA.EmployeeID, UA.TimeOffTypeID } equals new { rest.EmployeeID, rest.TimeOffTypeID } into penidngRequst
from penReq in penidngRequst.DefaultIfEmpty()
You can change
where penReq.TimeOffTypeID == UA.TimeOffTypeID
to
where penReq == null || penReq.TimeOffTypeID == UA.TimeOffTypeID
Is there any way to convert following SQL statement into LINQ?
select ve.EntityID
, fin1.FinanceStat as FinanceStat_New
, fin2.FinanceStat as FinanceStat_Old
from ValuationEvents_PIT_New as ve
left join FinStat_New as Fin1
on ve.EntityID = Fin1.EntityID
left join FinStat_Old as Fin2
on ve.EntityID = Fin2.EntityID
where Fin1.FinanceStat ne Fin2.FinanceStat
and Fin2.FinanceStat is not null
and charindex(Fin1.FinanceStat, 'abc') < 1
and charindex(Fin1.FinanceStat, 'xyz') < 1
Here is my version of it, but I need extra pair of eyes to look at it.
var result = (from ve in valuationEventsPit
join fsn in finStatNew on ve.EntityId equals fsn.EntityID into veFsn
from fin1 in veFsn.DefaultIfEmpty()
join fso in finStatOld on ve.EntityId equals fso.EntityID into veFso
from fin2 in veFso.DefaultIfEmpty()
select new
{
ve.EntityId,
FinStatNew1 = fin1 == null ? null : fin1.FinanceStat,
FinStatNew2 = fin2 == null ? null : fin2.FinanceStat
}).
Where(x => x.FinStatNew1 != null &&
x.FinStatNew2 != null &&
x.FinStatNew1 != x.FinStatNew2 &&
!(x.FinStatNew1.Contains("abc")) &&
!(x.FinStatNew1.Contains("xyz"))).ToList();
The reason I am excluding x.FinStatNew1 == null because of the charindex(Fin1.FinanceStat, 'abc') < 1, which will always return 0 if x.FinStatNew1 is not null and 'abc' or 'xyz' is not there and if x.FinStatNew1 is null then it will return null and condition still will be false (null < 0).
Thanks a lot for your help.
I think you could reduce that query even more and rearrange some things to make it more readable. Based on the original query and these are actually LINQ to objects queries, I'd try this:
const string con1 = "abc";
const string con2 = "xyz";
var query =
from ve in valuationEventPit
join fsn in finStatNew on ve.EntityId equals fsn.EntityID
join fso in finStatOld on ve.EntityId equals fso.EntityID
let FinStatNew = fsn.FinanceStat
let FinStatOld = fso.FinanceStat
where FinStatNew != FinStatOld && FinStatOld != null
&& new[]{con1,con2}.All(con => !FinStatNew.Contains(con))
select new { ve.EntityId, FinStatNew, FinStatOld };
The left join is not necessary here. Since you exclude the null values, we could just ignore them then and do the inner join.