Condition for list count and null - c#

I have following constructor as shown below:
public Delivery(DeliveryPeriodEnum deliveryPeriod, IEnumerable<DayOfWeek> days)
{
_deliveryPeriod = deliveryPeriod;
_days = days;
if (_deliveryPeriod == DeliveryPeriodEnum.Nothing
&& (_days != null || _days.Any()))
throw new GeneralException("There cannot be days for given period");
if (_deliveryPeriod != DeliveryPeriodEnum.Nothing
&& (_days == null || !_days.Any()))
throw new GeneralException("Period has to have at elast one item in list");
}
There are two business conditions:
//if DeliveryPeriodEnum.Nothing:
then days have to be either null or not null but with count = 0 otherwise show message
//if DeliveryPeriodEnum <> DeliveryPeriodEnum.Nothing:
then days cannot be null and have to have count > 0 otherwise show message
I have problems with it for instance in my first if statment if DeliveryPeriodEnum = DeliveryPeriodEnum .Nothing and days is null it also evalueates to _days.Any() which certainly raise error of instance not exist.
Keep in mind i would like to have both conditions in two lines if possible to avoid big if else statments etc..
EDIT:
if (_deliveryPeriod == DeliveryPeriodEnum.Nothing
&& _days != null && _days.Any())
throw new GenericException("There cannot be days for given period");
if ((_deliveryPeriod != DeliveryPeriodEnum.Nothing && _days != null && !_days.Any())
throw new GenericException("There cannot be days for given period");

Try to check by && not || as this condition can throw error _days != null || _days.Any()). Because _days can be null:
if (_deliveryPeriod == DeliveryPeriodEnum.Nothing
&& (_days != null && _days.Any()))
throw new GeneralException("There cannot be days for given period");
if (_deliveryPeriod != DeliveryPeriodEnum.Nothing
&& ((_days != null && !_days.Any()) || _days == null))
throw new GeneralException("Period has to have at elast one item in list");

First condition:
if DeliveryPeriodEnum.Nothing: then days have to be either null or not
null but with count = 0 otherwise show message
if (!((_deliveryPeriod == DeliveryPeriodEnum.Nothing) && (_days == null || !_days.Any())))
throw new GeneralException("There cannot be days for given period");
Second condition:
if DeliveryPeriodEnum <> DeliveryPeriodEnum.Nothing: then days cannot
be null and have to have count > 0 otherwise show message
if (!((_deliveryPeriod != DeliveryPeriodEnum.Nothing) && (_days != null) && _days.Any())))
throw new GeneralException("Period has to have at elast one item in list");

Just use the null-conditional operator like below. When _days is null the comparison leads to false in the first comparison and true in the second one. When it's not null, it just evaluates the .Any() statement.
public Delivery(DeliveryPeriodEnum deliveryPeriod, IEnumerable<DayOfWeek> days)
{
_deliveryPeriod = deliveryPeriod;
_days = days;
if (_deliveryPeriod == DeliveryPeriodEnum.Nothing && _days?.Any() == true)
throw new GeneralException("There cannot be days for given period");
if (_deliveryPeriod != DeliveryPeriodEnum.Nothing && (_days?.Any() ?? false) == false)
throw new GeneralException("Period has to have at least one item in list");
}

Related

Ternary condition in c# logic not working as desired

I have written a ternary condition in c# which isnt evaluating correctly. I am checking if both condition satisfy then it should return true otherwise false. At the moment it is returning true even if one condition fails. So even if the docType is Flashnotes is true, the canView is setting to true. Consider this IoC.Resolve().Authorize("Put", "ManageDocuments")
always returning true and docType may or may not return true
doc.canView = IoC.Resolve<IClientAuthorizationService>().Authorize("Put", "ManageDocuments") ==
AuthAccessLevel.Full && i.DOCUMENT_TYPE_ID != (int) DocumentType.FlashNotes ||
i.DOCUMENT_TYPE_ID != (int)DocumentType.CallMeetingNotes ||
i.DOCUMENT_TYPE_ID != (int)DocumentType.OtherNotes ||
i.DOCUMENT_TYPE_ID != (int)DocumentType.TearSheet
? true
: false;
If I've understood this correctly one of the i.DOCUMENT_TYPE_ID consditions must equate to true? Add parenthesis to equate that first.
doc.canView = IoC.Resolve<IClientAuthorizationService>().Authorize("Put", "ManageDocuments") ==
AuthAccessLevel.Full && (i.DOCUMENT_TYPE_ID == (int) DocumentType.FlashNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.CallMeetingNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.OtherNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.TearSheet)
Also there's no need for the true or false as it's already a bool.
I think what you're trying to do can be simplified into something like this:
var rejectedTypes = new[] { DocumentType.FlashNotes, DocumentType.CallMeetingNotes,
DocumentType.OtherNotes, DocumentType.TearSheet }.Cast<int>();
var accessLevel = IoC.Resolve<IClientAuthorizationService>()
.Authorize("Put", "ManageDocuments");
doc.canView = ((accessLevel == AuthAccessLevel.Full) &&
!rejectedTypes.Contains(i.DOCUMENT_TYPE_ID));
I think there's a mistake in the logic here. Try:
doc.canView = IoC.Resolve<IClientAuthorizationService>().Authorize("Put", "ManageDocuments") ==
AuthAccessLevel.Full && !(i.DOCUMENT_TYPE_ID == (int) DocumentType.FlashNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.CallMeetingNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.OtherNotes ||
i.DOCUMENT_TYPE_ID == (int)DocumentType.TearSheet);
It's an order of operations problem. You can find out more about ordering it here:
doc.canView = IoC.Resolve<IClientAuthorizationService>().Authorize("Put", "ManageDocuments") ==
AuthAccessLevel.Full && (i.DOCUMENT_TYPE_ID != (int) DocumentType.FlashNotes &&
i.DOCUMENT_TYPE_ID != (int)DocumentType.CallMeetingNotes &&
i.DOCUMENT_TYPE_ID != (int)DocumentType.OtherNotes &&
i.DOCUMENT_TYPE_ID != (int)DocumentType.TearSheet)
? true // Redundant code but included to show ternary operator
: false;

Not understanding LINQ query

I am maintaining a project and have come across some code which I can't understand. LINQ query:
var toDraw = from tile in testArr.AsEnumerable()
where tile.Item_Business_Unit != null ?
((tile.Ending_Date >= DateTime.Now || tile.Ending_Date == DateTime.MinValue) &&
((tile.Sales_Code == null) || (tile.Sales_Code.ToString() == customerNumber) ||
(tile.Sales_Code.ToString() == cpg)) && (tile.Unit_Price != 0)) :
((tile.Ending_Date >= DateTime.Now || tile.Ending_Date == DateTime.MinValue) &&
((tile.Sales_Code == null) || (tile.Sales_Code.ToString() == customerNumber) ||
(tile.Sales_Code.ToString() == cpg)) && (tile.Unit_Price != 0))
select tile;
From what I understand, from an array a tile is being selected which has the following criteria:
Ending date can be datetime.now or datetime.minvalue
Sales code can be null or can be equal to customer no or cpg
Unit price should be greater than 0
But I am not understanding why there is a conditional expression after tile.Item_Business_Unit since both of the conditions perform the same thing. So will the item be selected even if it has a null business unit? And does this work different from normal if/else operations?
Any suggestions would be very appreciated.
Are you being thrown by the shortcut notation?
x = (test_case) ? (true_part) : (false_part);
If test_case evaluates to true, you would have
Whereas if test_case evaluates to false, this expression would be evaluated
UPDATE:
As an FYI: The resulting test of both sides of that conditional expression above are equal, so that cryptic code is not even necessary.
You could replace that with this:
var toDraw = from tile in testArr.AsEnumerable()
where
((tile.Ending_Date >= DateTime.Now || tile.Ending_Date == DateTime.MinValue) &&
((tile.Sales_Code == null) || (tile.Sales_Code.ToString() == customerNumber) || (tile.Sales_Code.ToString() == cpg)) &&
(tile.Unit_Price != 0))
select tile;

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)
{
....
}

EF Non-static method requires a target

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

Categories

Resources