EF Non-static method requires a target - c#

I've serious problems with the following query.
context.CharacteristicMeasures
.FirstOrDefault(cm => cm.Charge == null &&
cm.Characteristic != null &&
cm.Characteristic.Id == c.Id &&
cm.Line != null &&
cm.Line.Id == newLine.Id &&
cm.ShiftIndex != null &&
cm.ShiftIndex.Id == actShiftIndex.Id &&
(newAreaItem == null ||
(cm.AreaItem != null &&
cm.AreaItem.Id == newAreaItem.Id)));
I get a TargetException: Non-static method requires a target when newAreaItem is null.
If newAreaItem is not null I get an NotSupportedException: Unable to create a constant value of type 'PQS.Model.AreaItem'. Only primitive types or enumeration types are supported in this context.
Things I've already checked if they're null:
c, newLine, actShiftIndex all 3 variables are not null and the Id is accessible.
I dont get it... please help.
If u need more information.. dont hesitate to ask...
UPDATE
I could eliminate the NotSupportedException, but I still got the TargetException when my newAreaItemIsNull is true.. :/
bool newAreaItemIsNull = (newAreaItem == null);
var mc = context.CharacteristicMeasures
.FirstOrDefault(cm => cm.Charge == null &&
cm.Characteristic != null &&
cm.Characteristic.Id == c.Id &&
cm.Line != null &&
cm.Line.Id == newLine.Id &&
cm.ShiftIndex != null &&
cm.ShiftIndex.Id == actShiftIndex.Id &&
(newAreaItemIsNull ||
(cm.AreaItem != null &&
cm.AreaItem.Id == newAreaItem.Id)));
UPDATE
I finally did it. It seems that the query parse can't parse my newAreaItem(IsNull) because it's not in the DB model somehow !?
I have to split my queries..
bool newAreaItemIsNull = (newAreaItem == null);
MeasureCharacteristic mc;
if (newAreaItemIsNull)
mc = context.CharacteristicMeasures
.FirstOrDefault(cm => cm.Charge == null &&
cm.Characteristic != null &&
cm.Characteristic.Id == c.Id &&
cm.Line != null &&
cm.Line.Id == newLine.Id &&
cm.ShiftIndex != null &&
cm.ShiftIndex.Id == actShiftIndex.Id);
else
mc = context.CharacteristicMeasures
.FirstOrDefault(cm => cm.Charge == null &&
cm.Characteristic != null &&
cm.Characteristic.Id == c.Id &&
cm.Line != null &&
cm.Line.Id == newLine.Id &&
cm.ShiftIndex != null &&
cm.ShiftIndex.Id == actShiftIndex.Id &&
cm.AreaItem != null &&
cm.AreaItem.Id == newAreaItem.Id);
Does someone know a better solution?

Try moving newAreaItem == null outside of the query
bool newAreaItemIsNull = (newAreaItem == null);
and replace newAreaItem == null with newAreaItemIsNull in query.
Query parser can only operate with the objects in the database, and newAreaItem is not one of them.

I had the exact same problem as you have when newAreaItem == null is true.
The problem comes from the fact that the item used in the LINQ cannot be null. Thus, when newAreaItem == null is true it means that newAreaItem is null and this leads to the error being thrown.
All you can do in my opinion is, after checking newAreaItem == null, to set the newAreaItem to a new empty object of that type if newAreaIteam is null. The newAreaItemIsNull condition will still be in place, thus the
(cm.AreaItem != null && cm.AreaItem.Id == newAreaItem.Id)
in your code below will still not be evaluated if newAreaItem is null.
context.CharacteristicMeasures.
FirstOrDefault(cm => cm.Charge == null &&
cm.Characteristic != null && cm.Characteristic.Id == c.Id &&
cm.Line != null && cm.Line.Id == newLine.Id &&
cm.ShiftIndex != null && cm.ShiftIndex.Id == actShiftIndex.Id &&
(newAreaItem == null ||
(cm.AreaItem != null && cm.AreaItem.Id == newAreaItem.Id)));

Related

I want to write LINQ where some condition may be null or not

I want to retrieve some data from database based on some condition, for this I'm using LINQ. But problem is that I don't know how to write LINQ when some condition may be null.
from x in _db.AirWorkOrder
join c in _db.Clients on x.ClientId equals c.Id
where x.CreatedOn >= model.StartDate && x.CreatedOn <= model.EndDate && x.ClientId == model.ClientId && x.Type == model.Type && x.WorkOrderStatus == model.Status
select new DateWisedReportItemModel
I want if the clientID, type, status have null value then it will take all the values saved in the DB. and if there are some values provided in it, then it will work according to the condition.
I presume you're asking how to wildcard things that are null. You need to make the particular clause true if your model value is null. You could do this by saying things like:
(dbcolumn == modelvalue || modelvalue == null) && ...
Or like
(dbcolumn == modelvalue == null ? dbvalue : modelvalue) && ...
Or like
(dbcolumn == modelvalue ?? dbvalue)
For example:
from x in _db.AirWorkOrder
join c in _db.Clients on x.ClientId equals c.Id
where
(x.CreatedOn >= model.StartDate ?? x.CreatedOn) &&
(x.CreatedOn <= model.EndDate == null ? x.CreatedOn : model.EndDate) &&
(x.ClientId == model.ClientId || model.ClientId == null) &&
...
I prefer the first as it is the most easy to understand. Also note carefully that it is the only one that will return the row if the row value in the db is null, because to a database null is never equal to null
I want if there is no condition given in ClientId, type and status then only date(this is mandatory) filter will apply, and if there is condition in these only then these(clientId, type and status) conditions will work
It might be most simple, in terms of code readability to do like:
var baseQuery = from x in _db.AirWorkOrder
join c in _db.Clients on x.ClientId equals c.Id
IEnumerable<...> result;
if(model.ClientId == null && model.Type == null && model.Status == null){
//search on date only
result = baseQuery.Where(x.CreatedOn >= model.StartDate && x.CreatedOn <= model.EndDate);
} else {
//search on no null client/type/status only
result = baseQuery.Where(x =>
(x.ClientId == model.ClientId || model.ClientId == null) &&
(x.Type == model.Type || model.Type == null) &&
(x.WorkOrderStatus == model.Status || model.Status == null);
}

Variable has a null value but if statement still gets called

I have an if statement
if (materialtype != "WINDOWVINYLREPL"
|| materialtype != "ROOFING"
&& materialtype != "null"
&& materialtype != null)
{
subtype = (from a in UEF.MaterialSubTypes
where a.MaterialSubType1.Equals(subtype) && a.Code.Contains(materialtype)
select a.Code).FirstOrDefault();
}
and even though materialtype is equal to null the if statement still gets called and it shouldn't be
if (materialtype != "WINDOWVINYLREPL" || ...
the variable is null so certainly it's not equal to "WINDOWVINYLREPL", hence this condition is true and it goes in.
You have an OR || condition. It should be like :
if (materialtype != "WINDOWVINYLREPL" && materialtype != "ROOFING" && materialtype != "null" && materialtype != null)
{
subtype = (from a in UEF.MaterialSubTypes where a.MaterialSubType1.Equals(subtype) && a.Code.Contains(materialtype) select a.Code).FirstOrDefault();
}
Condition was not written with proper brackets. AND, OR conflicted
if ((materialtype != "WINDOWVINYLREPL") || (materialtype != "ROOFING" && materialtype != "null")) && materialtype != null)
{
subtype = (from a in UEF.MaterialSubTypes where a.MaterialSubType1.Equals(subtype) && a.Code.Contains(materialtype) select a.Code).FirstOrDefault();
}
Your condition is equivalent to:
if((materialtype != "WINDOWVINYLREPL") || (materialtype != "ROOFING" && materialtype != "null" && materialtype != null))
Which is true if materialtype == null, because (materialtype != "WINDOWVINYLREPL") is true.
The && operator has higher priority than ||
Try to use parentheses to separate logic "OR" and "And"
Because if the value is null the test is always true
if ((materialtype != "WINDOWVINYLREPL" || materialtype != "ROOFING")
&& materialtype != null)
{
.....
}

Finding and comparing two objects, while avoiding NullReferenceException

I am trying to compare an original object to an updated one to find if they are different from each other. The compare logic should be as follows:
If neither object a nor b contains an object in SomeList, which has EType equal to EnumType.FooType, they should be evaluated as equals.
If only a xor b contains an object in SomeList, which has EType equal to EnumType.FooType, they should be evaluated as different.
If both objects contain an object as mentioned above, and the property Number is equal on both objects, then objects a and b should be evaluated as equals.
The following code solves the task, however it is long and bulky, so I ask if it can be shortened and made 'prettier'?
var a = original.SomeList.FirstOrDefault(p => p != null && p.EType == EnumType.FooEnum);
var b = updated.SomeList.FirstOrDefault(p => p != null && p.EType == EnumType.FooEnum);
var bEqual = false;
if (a == null && b == null)
bEqual = true;
else if (a != null && b != null)
bEqual = a.Number == b.Number;
return (a == null) ? (b == null) :
(b != null && a.Number == b.Number);
A better solution is to create a full set of equality functions and operators. This means implementing IEquatable and override Object.Equals(object). A total of four small functions would enable you to write:
return a == b;
MSDN has a good article about overriding equality functions.
How to: Define Value Equality for a Type (C# Programming Guide)
In C# 6.0 you can use the null propagation operator:
var a = original.SomeList.FirstOrDefault(p => p != null && p.EType == EnumType.FooEnum);
var b = updated.SomeList.FirstOrDefault(p => p != null && p.EType == EnumType.FooEnum);
return a?.Number == b?.Number;
Well straight off the bat you can do this
var a = original.SomeList.FirstOrDefault(p => p != null && p.EType == EnumType.FooEnum);
var b = updated.SomeList.FirstOrDefault(p => p != null && p.EType == EnumType.FooEnum);
var bEqual = false;
if (a == null && b == null)
bEqual = true;
else
bEqual = a.Number == b.Number;
You are already checking if they are null so if they are null then you are setting your bEqual to true; and if they aren't null then you can just perform the normal code below.
Now without testing your code I would think you could do something like this
if(original.SomeList.FirstOrDefault(p => p != null && p.EType == EnumType.FooEnum) != null && updated.SomeList.FirstOrDefault(p => p != null && p.EType == EnumType.FooEnum) != null)
bEqual = original.Number == updated.Number;
Something along those lines should be sufficient if I was at home I would test it for you and make sure but it should be close enough.
You can reduce it with conditional operator :
var a = original.SomeList.FirstOrDefault(p => p != null && p.EType == EnumType.FooEnum);
var b = updated.SomeList.FirstOrDefault(p => p != null && p.EType == EnumType.FooEnum);
bool bEqual = (a == null && b == null)? true :
(a != null && b != null)? a.Number == b.Number : false;

LINQ to entity Error: "Unable to create a null constant value of type ''System.Int32[]". Only entity types, enumeration types

I am receiving the error listed when executing a linq query on my RosterSummaryData_Subject_Local entity. I cannot seem to figure out what is wrong or a solution.
Unable to create a null constant value of type 'System.Int32[]'. Only
entity types, enumeration types or primitive types are supported in
this context.
My LINQ query on my code first entity context:
var subjLocal = customerContext.RosterSummaryData_Subject_Local.Where(s =>
(s.fkRosterSetID == 0) &&
(statsInfo.TestInstanceIDsList.Contains(s.fkTestInstanceID)) &&
(s.fkTestTypeID == statsInfo.TestTypeID) &&
(statsInfo.SchoolYearIDsList.Contains(s.fkSchoolYearID)) &&
(s.fkRosterTypeID == 1) &&
(s.fkSchoolID == 0) &&
(s.fkDepartmentID == 1) &&
(s.fkCourseID == 1) &&
(s.fkPeriodID == 1) &&
(statsInfo.DemoCatIDsList.Contains(s.fkDemoCommonCategoryID)) &&
(statsInfo.DemoCodeIDsList.Contains(s.fkDemoCommonCodeID)) &&
(statsInfo.TestSubjectIDsList.Contains(s.fkTest_SubjectID)));
It sounds like one of your Int32[] types is null. Try adding a check for that before accessing the .Contains methods:
var subjLocal = customerContext.RosterSummaryData_Subject_Local.Where(s =>
(s.fkRosterSetID == 0) &&
(statsInfo.TestInstanceIDsList != null &&
statsInfo.TestInstanceIDsList.Contains(s.fkTestInstanceID)) &&
(s.fkTestTypeID == statsInfo.TestTypeID) &&
(statsInfo.SchoolYearIDsList != null &&
statsInfo.SchoolYearIDsList.Contains(s.fkSchoolYearID)) &&
(s.fkRosterTypeID == 1) &&
(s.fkSchoolID == 0) &&
(s.fkDepartmentID == 1) &&
(s.fkCourseID == 1) &&
(s.fkPeriodID == 1) &&
(statsInfo.DemoCatIDsList != null &&
statsInfo.DemoCatIDsList.Contains(s.fkDemoCommonCategoryID)) &&
(statsInfo.DemoCodeIDsList != null &&
statsInfo.DemoCodeIDsList.Contains(s.fkDemoCommonCodeID)) &&
(statsInfo.TestSubjectIDsList != null &&
statsInfo.TestSubjectIDsList.Contains(s.fkTest_SubjectID)));
Alternatively, if it is Ok for them to be null (I assume it isn't, but just in case), you can change the above checks to follow this pattern:
(statsInfo.DemoCatIDsList == null ||
statsInfo.DemoCatIDsList.Contains(s.fkDemoCommonCategoryID)) &&

Checking multiple session variables if they are null

I am using the following to check a number of session variables:
if(MySession.Current.mpr != null && MySession.Current.mpr1 != null && MySession.Current.mpr2 != null
&& MySession.Current.mpr3 != null && MySession.Current.mip != null && MySession.Current.vr != null)
{
....
}
It does not work! I know one of the variables is not null.
Any suggestions?
Your if statement is written to only go inside the block if all variables are not null. To go inside if one variable is not null, use ors || instead of and &&:
if(MySession.Current.mpr != null || MySession.Current.mpr1 != null || MySession.Current.mpr2 != null
|| MySession.Current.mpr3 != null || MySession.Current.mip != null || MySession.Current.vr != null)
{
....
}

Categories

Resources