Variable has a null value but if statement still gets called - c#

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

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;

Combine linq queries together

I have to linq queries which have only a small difference between them. I am trying to merge them both.
.Where(i =>
!i.Username.StartsWith("e-") &&
i.SSN != null && i.SSN != "" &&
i.DisplayName != null && i.DisplayName != "" &&
i.LastName != null && i.LastName != "" &&
i.FirstName != null && i.FirstName != "")
.ToList();
and the other one is
.Where(i =>
!i.Username.StartsWith("e-") &&
i.SSN != null && i.SSN != "" &&
i.DisplayName != null && i.DisplayName != "" &&
i.LastName != null && i.LastName != "" &&
i.FirstName != null && i.FirstName != "" &&
i.WhenChanged.HasValue && i.WhenChanged.Value > DateTime.UtcNow.Add(_whenChangedTimeSpan))
.ToList();
as you can see only the last item in where clause is different. Can they both be merge together?
If you choice of either of the Linq Queries is based on a "condition", you could do the following.
var result = list.Where(
i => !i.Username.StartsWith("e-")
&& i.SSN != null && i.SSN != ""
&& i.DisplayName != null && i.DisplayName != ""
&& i.LastName != null && i.LastName != ""
&& i.FirstName != null && i.FirstName != ""
&& (condition?
i.WhenChanged.HasValue && i.WhenChanged.Value > DateTime.UtcNow.Add(_whenChangedTimeSpan)
: true)).ToList();
Since the second query is just a subset of the first query, first execute the first query and then run the filter over that result:
var result = (...).Where(
i => !i.Username.StartsWith("e-")
&& i.SSN != null && i.SSN != ""
&& i.DisplayName != null && i.DisplayName != ""
&& i.LastName != null && i.LastName != ""
&& i.FirstName != null && i.FirstName != ""
).ToList();
var filteredResult = result.Where(i.WhenChanged.HasValue && i.WhenChanged.Value > DateTime.UtcNow.Add(_whenChangedTimeSpan)).ToList();
This will run the query only once on the database, and will do the second part in memory on your app server.
Maybe you are looking for something like this.
Create a method to do the common check
bool CommonCheck(TypeOfYourVariable i)
{
return !i.Username.StartsWith("e-") &&
i.SSN != null && i.SSN != "" &&
i.DisplayName != null && i.DisplayName != "" &&
i.LastName != null && i.LastName != "" &&
i.FirstName != null && i.FirstName != "";
}
Use it like this:
// first
.Where(i => CommonCheck(i))
.ToList();
// secpmd
.Where(i => CommonCheck(i) &&
i.WhenChanged.HasValue && i.WhenChanged.Value > DateTime.UtcNow.Add(_whenChangedTimeSpan))
.ToList();
Update, or you can do this:
var firstQueryResult = yourInput.Where(i =>
!i.Username.StartsWith("e-") &&
i.SSN != null && i.SSN != "" &&
i.DisplayName != null && i.DisplayName != "" &&
i.LastName != null && i.LastName != "" &&
i.FirstName != null && i.FirstName != "" &&
).ToList();
var secondQueryResult = firstQueryResult
.Where(i=> i.WhenChanged.HasValue && i.WhenChanged.Value > DateTime.UtcNow.Add(_whenChangedTimeSpan))
.ToList();

Updating different Objects that have same properties

In my Code, i've got three (or more...) different objects, that all have the same properties (e.g. TrackingItemType, ReaderID etc).
They are derived from CounterBase (which does not have the Properties needed, but others).
Now i want to iterate through a Collection of those objects. In the Collection, all of the three objects can occur. Therefore, currently i've implemented the "update" for each object seperately.
Question: How can I avoid that duplicate Code written? Is there any
pattern available to update the different objects with same
properties?!
THANKS!
Method of interest:
private void UpdateTrackingCounters(Reading readingData, TrackingItemType trackingItemType, string trackingCounterType)
{
try
{
foreach (CounterBase counter in this.TrackingCounters)
{
if (typeof(TrackingSimpleCounter).IsInstanceOfType(counter))
{
TrackingSimpleCounter trackingCounter = (TrackingSimpleCounter)counter;
if (trackingCounter.TrackingCounterType == trackingCounterType)
{
if ((trackingCounter.ReaderID == 0
&& trackingCounter.TrackingItemType == null)
|| (trackingCounter.ReaderID == 0
&& trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
|| (trackingCounter.ReaderID == readingData.ReaderId
&& trackingCounter.TrackingItemType == null)
|| (trackingCounter.ReaderID == readingData.ReaderId
&& trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
)
{
trackingCounter.IncreaseOne();
}
}
}
else if (typeof(TrackingIntervalBasedRollingCounter).IsInstanceOfType(counter))
{
TrackingIntervalBasedRollingCounter trackingCounter = (TrackingIntervalBasedRollingCounter)counter;
if (trackingCounter.TrackingCounterType == trackingCounterType)
{
if ((trackingCounter.ReaderID == 0
&& trackingCounter.TrackingItemType == null)
|| (trackingCounter.ReaderID == 0
&& trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
|| (trackingCounter.ReaderID == readingData.ReaderId
&& trackingCounter.TrackingItemType == null)
|| (trackingCounter.ReaderID == readingData.ReaderId
&& trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
)
{
trackingCounter.IncreaseOne();
}
}
}
else if (typeof(TrackingTriggerBasedRollingCounter).IsInstanceOfType(counter))
{
TrackingTriggerBasedRollingCounter trackingCounter = (TrackingTriggerBasedRollingCounter)counter;
if (trackingCounter.TrackingCounterType == trackingCounterType)
{
if ((trackingCounter.ReaderID == 0
&& trackingCounter.TrackingItemType == null)
|| (trackingCounter.ReaderID == 0
&& trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
|| (trackingCounter.ReaderID == readingData.ReaderId
&& trackingCounter.TrackingItemType == null)
|| (trackingCounter.ReaderID == readingData.ReaderId
&& trackingCounter.TrackingItemType == trackingCounter.TrackingItemType)
)
{
trackingCounter.IncreaseOne();
}
}
}
}
}
catch (Exception ex)
{
this.Trace.Error(ex);
}
}
Define an interface that contains the properties and method you need:
interface ITrackable
{
int ReaderID;
string TrackingItemType;
void IncreaseOne();
}
And add it to the declaration of each class that has them:
class TrackingSimpleCounter : CounterBase, ITrackable
class TrackingIntervalBasedRollingCounter: CounterBase, ITrackable
class TrackingTriggerBasedRollingCounter : CounterBase, ITrackable
If all the classes truly share those properties, you won't have to implement any of the interface, since it'll already be present.
Then all you need is
foreach (ITrackable counter in this.TrackingCounters)
{
if ((counter.ReaderID == 0 && counter.TrackingItemType == null)
|| (counter.ReaderID == 0 && counter.TrackingItemType == counter.TrackingItemType)
|| (counter.ReaderID == readingData.ReaderId && counter.TrackingItemType == null)
|| (counter.ReaderID == readingData.ReaderId && counter.TrackingItemType == counter.TrackingItemType)
)
{
counter.IncreaseOne();
}
}
Although unless I misunderstand your logic all you truly need is:
foreach (ITrackable counter in this.TrackingCounters)
{
if (counter.ReaderID == 0 || counter.ReaderID == readingData.ReaderID)
{
counter.IncreaseOne();
}
}
Or if you want to use LINQ:
foreach (var counter in this.TrackingCounters.OfType<ITrackable>().Where(c => c.ReaderID == 0 || c.ReaderID = readingData.ReaderID))
{
counter.IncreaseOne();
}
Factorize
You can extract the common properties into one new common Object, and make both of your class have a reference property to that object.
This way, when you update this object, both of your original objects will have the most up-to-date values, without risk to forgot to update one of the properties.

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