NullReferenceException on outer join - c#

I am trying to grab all data from FDerive, however I am try to set a filter with a where clause. Unfortunately I am getting a nullreferencexpection when I touch spd when a row in spd is null.
var Result = from fpd in FDerive
join spd in SDerive
on new { fpd.PId, fpd.SId }
equals new { spd.PId, spd.SId } into allRows
from spd in allRows.DefaultIfEmpty()
where spd.SId == ""
|| spd.PId == ""
select new { fpd, spd };
How do I get around the null error?

DefaultIfEmpty<T> will return a set containing only one element with the default value of T - in this case null - if the source collection is empty. So spd will be null if there are no items returned in the join.
Try to a null check in the where clause
var Result =
...
where spd == null || spd.SId == "" || spd.PId == ""
select new { fpd, spd };

I found the answer at the bottom of the code in the following question
LINQ double left join
var results =
from person in students
join entry in subquery on person.FullName equals entry.AuthorFullName into personEntries
from personEntry in personEntries.DefaultIfEmpty()
orderby person.FullName
select new
{
PersonName = person.FullName,
BlogTitle = personEntry == null ? "" : personEntry.Title
};

Related

Get one field value from LINQ query

I need to get one value of the q2.RoomId in this linq query as below and pass it to string variable . and is it possible to set alias column name for select ?
var result = from q1 in _db.DormApplications
join q2 in _db.DormRooms
on q1.DormRoomId equals q2.Id
where q1.Poster == username && q1.Review == EnableType.YES
&& now > q1.Sdate && now <q1.Edate
select new { q1.Name, q1.Sdate, q1.Edate, q1.DormRoomId,
q2.RoomId };
I tried this to get q2.RoomId ,
String room = result[4].ToString();
but still cannot work ,please anyone can help me ?
If you know the query will only return one row you can write:
var result = (from q1 in _db.DormApplications
join q2 in _db.DormRooms
on q1.DormRoomId equals q2.Id
where
q1.Poster == username && q1.Review == EnableType.YES
&& now > q1.Sdate && now <q1.Edate
select
new {
q1.Name,
q1.Sdate,
q1.Edate,
q1.DormRoomId,
q2.RoomId
}).FirstOrDefault();
var roomId = result.RoomId;
var Name = result.Name;

left join linq when right list is empty

pdlist = (from a in context.EMPLOYEES
join b in context.PERSONS on a.PERSON_ID equals b.PERSON_ID
where a.SUPERVISOR_ID == empId
select new Pollidut.Models.Pollidut
{
PollidutId = a.EMPLOYEE_ID,
PollidutName = b.PERSON_NAME,
DistributionHouseId = a.DISTRIBUTION_HOUSE_ID == null ? 0 : (int)a.DISTRIBUTION_HOUSE_ID
}).ToList();
DateTime dt = DateTime.Now.Date;
var pdTargets = (from p in context.PALLYDUT_TARGET
where p.Active == true && p.StartDate <= dt && p.EndDate >= dt
group p by p.PallydutId into g
select new
{
PollidutId = g.Key,
Start = g.Select(x => x.StartDate).Min(),
End = g.Select(y => y.EndDate).Max(),
Target = g.Select(z => z.Target).Sum()
}).ToList();
var PdTargetsList = (from m in pdlist
join n in pdTargets on m.PollidutId equals n.PollidutId into t
from l in t.DefaultIfEmpty()
select new
{
PallydutId = m.PollidutId,
PallydutName = m.PollidutName,
DistributionId = m.DistributionHouseId,
StartDate = l.Start == null ? dt : l.Start,
EndDate = l.End == null ? dt : l.End,
Target = l.Target == null ? 0 : l.Target
}).ToList();
pdlist is employee list where pdTarget may set or not. pdTarget can be empty. When I left join pdlist with pdTargets I get Object reference not set error. pdTargets collection returns null.How to fix it. Anybody helps me greatly appreciated.
The reason I suspect why you are getting a Null reference exception is because your are directly accessing the properties on a null object (l in your case), even though you are using a DefaultIfEmpty() method which is going to return null if no matching rows are found. You should change your code like this:-
select new
{
PallydutId = m.PollidutId,
PallydutName = m.PollidutName,
DistributionId = m.DistributionHouseId,
StartDate = l == null ? dt : l.Start,
EndDate = l == null ? dt : l.End,
Target = l == null ? 0 : l.Target
}).ToList();
Also, If you think that your one object pdTarget can be null, then I don't think its about a left join or a normal join, your code will throw an exception in either case. Please check this MSDN documentation to handle nulls in query expressions.

linq - left outer join with where returning list of nulls

Here is the full query(without the where), that works:
public List<TipoResiduo> filtro(TipoResiduo objent)
{
using (var db = new DBEntities())
{
var consulta = (from a in db.tb006_tipo_residuo
join cr in db.tb016_classe_residuo on a.fk_id_classe_residuo equals cr.id into trcr
from classeresiduo in trcr.DefaultIfEmpty()
join gr in db.tb017_grupo_residuo on a.fk_id_grupo_residuo equals gr.id into trgr
from gruporesiduo in trgr.DefaultIfEmpty()
join tfg in db.tb008_tipo_fonte_geradora on a.fk_id_tipo_fonte_geradora equals tfg.id into trtfg
from tipofontegeradora in trtfg.DefaultIfEmpty()
join civig in db.tb051_categoria_ivig on a.fk_id_categoria_ivig equals civig.id into trci
from categoriaivig in trci.DefaultIfEmpty()
join icap in db.tb048_ibama_capitulo on a.fk_id_ibama_capitulo equals icap.id into tric
from ibamacapitulo in tric.DefaultIfEmpty()
join isubcap in db.tb049_ibama_subcapitulo on a.fk_id_ibama_subcapitulo equals isubcap.id into tris
from ibamasubcapitulo in tris.DefaultIfEmpty()
join ires in db.tb050_ibama_residuo on a.fk_id_ibama_residuo equals ires.id into trir
from ibamaresiduo in trir.DefaultIfEmpty()
//where a.fk_id_classe_residuo == objent.fk_id_classe_residuo
select new TipoResiduo()
{
id = a.id,
no_tipo_residuo = a.no_tipo_residuo,
dt_cadastro = a.dt_cadastro,
fk_id_classe_residuo = a.fk_id_classe_residuo,
fk_id_grupo_residuo = a.fk_id_grupo_residuo,
nu_densidade = a.nu_densidade,
fk_id_tipo_fonte_geradora = a.fk_id_tipo_fonte_geradora,
fk_id_categoria_ivig = a.fk_id_categoria_ivig,
fk_id_ibama_capitulo = a.fk_id_ibama_capitulo,
fk_id_ibama_subcapitulo = a.fk_id_ibama_subcapitulo,
fk_id_ibama_residuo = a.fk_id_ibama_residuo,
no_classe_residuo = classeresiduo == null ? String.Empty : classeresiduo.no_classe_residuo,
no_grupo_residuo = gruporesiduo == null ? String.Empty : gruporesiduo.no_grupo_residuo,
no_tipo_fonte_geradora = tipofontegeradora == null ? String.Empty : tipofontegeradora.no_tipo_fonte_geradora,
no_categoria_ivig = categoriaivig == null ? String.Empty : categoriaivig.no_categoria_ivig,
no_ibama_capitulo = ibamacapitulo == null ? String.Empty : ibamacapitulo.de_ibama_capitulo,
no_ibama_subcapitulo = ibamasubcapitulo == null ? String.Empty : ibamasubcapitulo.de_ibama_subcapitulo,
no_ibama_residuo = ibamaresiduo == null ? String.Empty : ibamaresiduo.de_ibama_residuo
});
return consulta.OrderBy(a => a.no_tipo_residuo).ToList();
}
}
My object TipoResiduo has some virtual fields just for convenience and can have some null fields.
And when I try to filter with the where(removing the //) the query shows nothing. The ObjEnt of the function has some fields previously populated, and when the field is null, I want to show all.
I tried this too, and nothing:
where a.fk_id_classe_residuo ==
(objent.fk_id_classe_residuo == null
? 0 : objent.fk_id_classe_residuo)
I'm new at this, what should I do to make this work?
You have no left outer join so I don't understand the title
If objent.fk_id_classe_residuo is null this will find a.fk_id_classe_residuo = 0 - not all
where a.fk_id_classe_residuo == (objent.fk_id_classe_residuo == null ? 0 : objent.fk_id_classe_residuo)
try this
where objent.fk_id_classe_residuo == null
or a.fk_id_classe_residuo == objent.fk_id_classe_residuo
After hitting my head into the wall, I found the answer:
where objent.fk_id_classe_residuo == 0 ? true : classeresiduo.id == null
&& classeresiduo.id == null ? false : a.fk_id_classe_residuo == objent.fk_id_classe_residuo
The problem is this objent.fk_id_classe_residuo comes from a dropdownlist, and I set this fk_id as 0 when no option is given. Well, would be very difficult to someone help me with this. :|
But I thank Blam for his attention. ;)

linq left outer join object reference not set to an instance of an object

i am using left outer join in this query below. the variable fgi is coming null so so the line after that in where it giving object reference error. how can solve it?.
var a = (from e1 in _db.Features.ToList()
where e1.int_ParentId==0 && e1.bit_IsModule == true & e1.bit_ShowInMenu == true && e1.bit_Activate == true
join e2 in _db.OrganizationModules on e1.int_FeatureId equals e2.int_FeatureId into fg
from fgi in fg.DefaultIfEmpty()
where fgi.bit_OrganizationModuleActiveDeactive != false && fgi.int_OrganizationId == SepiaCMS.Models.Security.Authorization.OrganizationID // object reference not set to instance of an object
orderby e1.int_FeaturesSortID ascending, e1.int_FeatureId descending
select new FeatureViewModel
{
featureid = e1.int_FeatureId,
featurename = e1.vcr_FeaturesName,
classes = path == e1.vcr_LinkName ? "<li class=active>" + Html.ActionLink(e1.vcr_FeaturesName, e1.vcr_LinkName.Substring(e1.vcr_LinkName.IndexOf('/') + 1), e1.vcr_LinkName.Substring(0, e1.vcr_LinkName.IndexOf('/')), new { area = string.IsNullOrEmpty(e1.vcr_Area) == true ? "" : e1.vcr_Area }, new { #class = e1.vcr_CssClass }) + "</li>" : "<li>" + Html.ActionLink(e1.vcr_FeaturesName, e1.vcr_LinkName.Substring(e1.vcr_LinkName.IndexOf('/') + 1), e1.vcr_LinkName.Substring(0, e1.vcr_LinkName.IndexOf('/')), new { area = string.IsNullOrEmpty(e1.vcr_Area) == true ? "" : e1.vcr_Area }, new { #class = e1.vcr_CssClass }) + "</li>"
}).ToList();
Since you are doing a left join i guess you want to include the null values. Just add
where fgi == null || (....)
Or if you don't want the null values just change the query to an inner join.

Left join is not working for complex query

I have very complex linq query which is working fine for inner join, i.e., without z_temp.DefaultIfEmpty(). But when I use this for left join, The query is not yielding results.
var q = from x in db.EmployeesList
where x.EmployeesListStartDate >= startDate && x.EmployeesListStartDate <= endDate
join y in db.Survey on x.Survey.SurveyID equals y.SurveyID
join z in
(from a in db.Commit
join b in
(from commit in db.Commit
where
commit.CommitListID != null &&
commit.CommitType.ToUpper() != "PREVIEW"
group commit by new
{
commit.CommitListID
} into g
select new
{
CommitListID = (Int32?)g.Key.CommitListID,
CommitId = (Int32?)g.Max(p => p.CommitId)
})
on new { a.CommitListID, a.CommitId }
equals new { b.CommitListID, CommitId = (Int32)b.CommitId }
select new
{
CommitListID = (Int32?)a.CommitListID,
CommitUsername= a.CommitUsername,
CommitStartDateTime=a.CommitStartDateTime,
CommitType=a.CommitType,
CommitSuccessCount=a.CommitSuccessCount
}) on new { EmployeesListID = x.EmployeesListID } equals new { EmployeesListID = (Int32)z.CommitListID }
into z_temp
from _z in z_temp.DefaultIfEmpty()
select new CustomEmployeesList
{
SurveyId = x.Survey.SurveyID != null ? (int)x.Survey.SurveyID : 0,
EmployeesListId = x.EmployeesListID != null ? (int)x.EmployeesListID : 0,
EmployeesListName = x.EmployeesListName,
SpecificMessage = x.SpecificMessage,
ListCriteria = x.ListCriteria,
Channel = x.Channel,
EmployeesListStartDate = (DateTime)x.EmployeesListStartDate,
EmployeesListEndDate = (DateTime)x.EmployeesListEndDate,
Records = x.Records != null ? (int)x.Records : 0,
QueryId = x.AppSqlQueries.QueryId != null ? (int)x.AppSqlQueries.QueryId : 0,
//AuditId = (Int32?)x.AuditEntry.AuditId,
StatusCommonCode = x.CommonCode.CommonCodeId != null ? (int)x.CommonCode.CommonCodeId : 0,
SurveyName = y.SurveyName,
LastCommitDateTime = _z.CommitStartDateTime.HasValue ? (DateTime)_z.CommitStartDateTime : DateTime.MinValue,
LastCommitType = _z.CommitType != null ? _z.CommitType : "",
LastCommitUsername = _z.CommitUsername != null ? _z.CommitUsername : "",
LastCommitCount = _z.CommitSuccessCount.HasValue ? (int)_z.CommitSuccessCount : 0
};
This is returning no results and
I am getting this exception message while viewing results in debug mode:
LINQ to Entities does not recognize the method
'System.Collections.Generic.IEnumerable1[<>f_AnonymousType351[<>f_AnonymousType35%5bSystem.Nullable1[System.Int32],System.String,System.Nullable1%5bSystem.DateTime%5d,System.String,System.Nullable`1%5bSystem.Int32%5d%5d%5d">System.Nullable1[System.Int32],System.String,System.Nullable1[System.DateTime],System.String,System.Nullable1[System.Int32]]]
DefaultIfEmpty[<>f__AnonymousType35' method, and this method cannot be
translated into a store expression.
Can anyone suggest the where the problem would be, this would be really helpful!
The problem is in this line:
from _z in z_temp.DefaultIfEmpty()
Calling DefaultIfEmpty() will return null if no rows matches the join. Ok, you a left join, but you have to test if _z is null before access its members:
...
LastCommitDateTime = _z == null ? DateTime.MinValue : (_z.CommitStartDateTime.HasValue ? (DateTime)_z.CommitStartDateTime : DateTime.MinValue),
LastCommitType = _z == null ? "" : (_z.CommitType != null ? _z.CommitType : ""),
...
etc.
A more elegant alternative is create a class that defines the fields you want and call _z.DefaultIfEmpty(new ZRow()), so you don't need to test if _z is null every time you need it. But in this case you'll need to change the select that produces the result for z_temp and replace it to select new ZRow(a.CommitListID, etc..). Not a big deal.

Categories

Resources