I'm writing a program that uses Entity Framework and linq. The problem is with the query arInvArea and especially in the where clause. In WithSwimmingPool there are zero values and therefore I get null reference exception. How can I catch such exception in the where clause. Other solutions in Stackoverflow didn't help me. Thanks
private ObjectContactsRow CreateNewRow(AreaInventory arInv)
{
// Here in the where clause I get exception ! WithSwimmingPool is from type bool
var arInvArea = arInv.Area.Where(p => p.WithSwimmingPool)
.Select(p => p.Units(ReportDate))
.FirstOrDefault();
return new ObjectContactsRow()
{
areaSize = arInvArea
};
}
public partial class Area
{
public bool WithSwimmingPool => AreaArt.AreaUnit_ID == "SWMP";
}
public class ObjectContactsRow
{
public double areaSize { get; set; }
public override object[] GetExcelRow()
{
var index = 0;
Row[index++] = areaSize;
return Row;
}
}
You have to change your query to:
var arInvArea = arInv.Area.Where(p => p != null && p.WithSwimmingPool)
.Select(p => p.Units(ReportDate))
.FirstOrDefault();
Your collection may include NULL indexes and that leads to p == null in your query.
If by any chance you are using C# 8, you can enable nullable by including #nullable enable in your code. That then points out to all code segments with a null reference error potency.
Related
I am trying to use FirstOrDefault in my code but getting compile time error.
Cannot implicitly convert type Priority to bool
public class Priority
{
public string Name { get; set; }
public string Id { get; set; }
public string Default { get; set; }
}
public class ProcedureStatus
{
public string Id { get; set; }
public Priorities Priorities { get; set; }
}
public class Priorities
{
public List<Priority> Priority { get; set; }
}
foreach (Priority priority in status.Priorities.Priority)
{
if (priority.Default == "true" && grid.Priority == null)
{
grid.Priority = priority.Id;
grid.PriorityText = priority.Name;
SetPriority(gridRow);
break;
}
else if (status.Priorities.Priority.FirstOrDefault(x => x.Id == priority.Id))
priority.Default = "true";
}
How to use FirstOrDefault in my scenario.
You are using status.Priorities.Priority.FirstOrDefault(x => x.Id == priority.Id) in an if clause.
The if clause is expecting an expression that returns a bool, but your expression returns a Priority.
Aside from that, it looks like the if clause is redundant, since you are iterating the properties via a foreach and trying to get the current item from the list you are already iterating. If you just want to iterate the list, you don't need the if clause.
The way you would typically use FirstOrDefault would be like this:
var priority = status.Priorities.Priority.FirstOrDefault(x => x.Id == priorityId)`;
if (priority != null)
{
\\ ...
}
where priorityId is the ID of the priority you are looking for.
This does not seem useful inside you foreach loop though.
(Even after your question update, you still have the same if clause inside the foreach. It's just after an if/else now.)
The problem
The problem is not related to Lambda expressions (x => blablabla syntax) but related to what a specific function FirstOrDefault() returns and how to use it in an if-else-elseif scenario.
Analysis
The code you wrote could be written in two steps as:
if (priority.Default == "true" && grid.Priority == null)
{
// your if block
}
else
{
Priority firstPriority = status.Priorities.Priority.FirstOrDefault(x => x.Id == priority.Id);
// Same exact error you got... Cannot implicitly convert type Priority to bool
if (firstPriority) {
priority.Default = "true";
}
}
Now it is more easy to understand what the problem is... if, else and else if statements need a logical expression to work. That can be made either using a bool variable or doing a check/evaluation that returns true/false.
Solution
There are many different ways to address the problem:
You could use a function that directly returns a boolean like Any(), that would be useful if you do not need to use the object matching the x => x.Id == priority.Id.
You could use FirstOrDefault() but changing your else if to convert it into something that return a logic expression. This would be useful if you need to later work with that element.
Using the Any() function
else if (status.Priorities.Priority.Any(x => x.Id == priority.Id))
{
priority.Default = "true"; // Dumb question, why the Default property is not of type bool???
}
Using the FirstOrDefault()
Note: you have already been given this option in other answers. Ergwun's answer and Braulio's answer so far.
As per the documentation of the function I linked and what its name suggests, if the FirstOrDefault() function does not find anything, it returns null. So you could check it whatever it returns is null or not.
This could be done in a couple of ways. Depending on if you need to later work with whatever the function returns or not.
else if (status.Priorities.Priority.FirstOrDefault(x => x.Id == priority.Id) != null)
{
priority.Default = "true";
}
or
if (priority.Default == "true" && grid.Priority == null)
{
// your if block
}
else
{
Priority firstPriority = status.Priorities.Priority.FirstOrDefault(x => x.Id == priority.Id);
if (firstPriority != null) {
priority.Default = "true";
Console.WriteLine("The description of the priority if the Id XXXX is: " + firstPriority.Description);
}
}
Best way it's to compare if your object is not null after the research
foreach (Priority priority in status.Priorities.Priority)
{
if (grid.Priority == null)
{
grid.Priority = priority.Id;
grid.PriorityText = priority.Name;
break;
}
else if (status.Priorities.Priority.FirstOrDefault(x => x.Id == priority.Id) != null)
// You found something, do this.
}
Try it
I have a list of errors defined as the following:
List<Errors> test1 = new List<Errors>();
public class Errors
{
public int ID {get; set;}
public int Occurrence {get; set;}
//.....
//.....
}
The errors are unique by the combination of the two fields above.
A second list keeps track of whose been assigned to the errors.
List<Tasks> test2 = new List<Tasks>();
public class Tasks
{
public int ID {get; set;}
public int Occurrence {get; set;}
public int EmployeeID {get; set;}
//.....
}
Also made unique by the same two fields. Essentially the tasks are a subset of the errors that have been assigned to someone.
I would like to use a LINQ query (or equivalent) to determine if the composite ID from the List<Errors> exists in List<Tasks>... To be clear it must use both IDS.
I have found the below solution but have not been able to adopt it to a composite key.
`var test2NotInTest1 = test2.Where(t2 => !test1.Any(t1 => t2.Contains(t1)));`
Just need to use and && operator and check both properties instead of one:
var test2NotInTest1 = test2.Where(t2 => !test1.Any(t1 => t1.ID == t2.ID && t1.Occurance == t2.Occurance);
There is a function for that... Except
var test2NotInTest1 = test1.Except(test2);
If you don't have it you will need to create the interface for equal -- something like this:
var test2NotInTest1 = test1.Except(test2, new ErrorsComparer());
class ErrorsComparer : IEqualityComparer<Errors>
{
public bool Equals(Errors x, Errors y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
//Check whether the products' properties are equal.
return x.ID == y.ID && x.Occurrence == y.Occurrence;
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public int GetHashCode(Errors e)
{
if (Object.ReferenceEquals(e, null)) return 0;
int hashID = e.ID == null ? 0 : e.ID.GetHashCode();
int hashO = e.Occurrence.GetHashCode();
//Calculate the hash code for the product.
return hashID ^ hashO;
}
}
You were almost there, just add a correct condition to the LINQ expression:
var test2NotInTest1 = listOfErrors.Where(e => !listOfTasks.Any(t => t.ID == e.Id && t.Occurrence == e.Occurrence)).ToList();
For: to determine if the composite ID from the Errors exists in Tasks...
Another approach is to use Enumerable.Join Method
var assignedErrors =
errors.Join(tasks,
error => new { Id = error.Id, Occurrence = error.Occurrence },
task => new { Id = task.Id, Occurrence = task.Occurrence },
(error, task) => error);
For: to determine if the composite ID from the Errors not exists in Tasks..., as in your sample:
var test2NotInTest1 = test2.Where(t2 => !test1.Any(t1 => t2.Contains(t1)));
You can use HashSet to "speed up" search for already assigned errors.
var assignedErrors = tasks.Select(task => (task.Id, task.Occurrence)).ToHashSet();
var notAssignedErrors =
errors.Where(error => assignedErrors.Contains((error.Id, error.Occurrence)) == false)
.ToList();
Or create your own domain specific extension method:
public static IEnumerable<Errors> NotAssignedIn(
this IEnumerable<Errors> errors,
IEnumerable<Tasks> tasks)
{
var assigned = new HashSet<(int Id, int Occurrence)>();
foreach (var task in tasks)
{
assigned.Add((task.Id, task.Occurrence));
}
foreach (var error in errors)
{
if (assigned.Contains((error.Id, error.Occurrence)) == false)
{
yield return error;
}
}
}
Usage:
var notAssignedErrors = errors.NotAssignedIn(tasks);
I have list of Countries and inside it have list of Places.
// ...
public IList<ICountriesDTO> Countries { get; set; }
public class CountriesDTO: ICountriesDTO
{
public IEnumerable<IPlacesDTO> Places { get; set;
}
I am trying to get list of Places that are not null.
allPlacesDTO.World.Countries
.SelectMany(x => x.Places == null ? null : x.Places)
.ToList();
But I receive a null exception when Places are null for their Countries object.
How can I do a null check for Places and just use return statement instead of doing select to null object, similar to what I have below?
if (allPlacesDTO.World.Countries.Places == null)
{
return;
}
Update:
My requirement was if there is no places in any of the countries just use the return statement to exit the current function without proceeding further. That was achieved by the accepted answer and Count function.
var lstAllPlaces = allPlacesDTO.World.Countries
.Where(x => x.Places != null)
.SelectMany(x => x.Places)
.ToList();
if (lstAllPlaces.Count() == 0)
{
return;
}
You can do the condition in where clause
allPlacesDTO.World.Countries.Where(x => x.Places != null)
.SelectMany(x => x.Places).ToList();
Or change the ternary operator to return new List() (it can be greedy)
I have the following ugly code:
if (msg == null ||
msg.Content == null ||
msg.Content.AccountMarketMessage == null ||
msg.Content.AccountMarketMessage.Account == null ||
msg.Content.AccountMarketMessage.Account.sObject == null) return;
Is there a way to chain check for null values in C#, so that I don't have to check each individual level?
One of the proposals in C# 6 would be to add a new Null Propogation operator.
This will (hopefully) allow you to write:
var obj = msg?.Content?.AccountMarketMessage?.Account?.sObject;
if (obj == null) return;
Unfortunately, there is nothing in the language at this point that handles this.
There is not currently such a thing, but it may be coming to .NET very soon. There is a well-known User Voice thread on the subject. And as noted in this article, the Visual Studio team has recently announced that:
We are seriously considering this feature for C# and VB, and will be
prototyping it in coming months.
Edit: and as noted in Reed Copsey's answer above, it is now a planned addition for C# 6. There are better details on the Codeplex pages he linked.
There is no built-in support for this, but you can use an extension method for that:
public static bool IsNull<T>(this T source, string path)
{
var props = path.Split('.');
var type = source.GetType();
var currentObject = type.GetProperty(props[0]).GetValue(source);
if (currentObject == null) return true;
foreach (var prop in props.Skip(1))
{
currentObject = currentObject.GetType()
.GetProperty(prop)
.GetValue(currentObject);
if (currentObject == null) return true;
}
return false;
}
Then call it:
if ( !msg.IsNull("Content.AccountMarketMessage.Account.sObject") ) return;
You need monads and Monadic null checking. Could have a look at Monads.Net package. It can help with simplifying null tests and getting values from deep navigation properties
Something like
var sObject = person.With(p=>p.Content).With(w=>w.AccountMarketMessage ).With(p=>p.Account).With(p=>p.Object);
If you wanted a default value then
var sObject = person.With(p=>p.Content).With(w=>w.AccountMarketMessage).With(p=>p.Account).Return(p=>p.Object, "default value");
You can lazily evaluate the values using lambda expressions. This is overkill for a simple null check, but can be useful for chaining more complex expressions in a "fluent" manner.
Example
// a type that has many descendents
var nested = new Nested();
// setup an evaluation chain
var isNull =
NullCheck.Check( () => nested )
.ThenCheck( () => nested.Child )
.ThenCheck( () => nested.Child.Child )
.ThenCheck( () => nested.Child.Child.Child )
.ThenCheck( () => nested.Child.Child.Child.Child );
// handle the results
Console.WriteLine( isNull.IsNull ? "null" : "not null" );
Code
This is a full example (albeit draft-quality code) that can be pasted into a console app or LINQPad.
public class Nested
{
public Nested Child
{
get;
set;
}
}
public class NullCheck
{
public bool IsNull { get; private set; }
// continues the chain
public NullCheck ThenCheck( Func<object> test )
{
if( !IsNull )
{
// only evaluate if the last state was "not null"
this.IsNull = test() == null;
}
return this;
}
// starts the chain (convenience method to avoid explicit instantiation)
public static NullCheck Check( Func<object> test )
{
return new NullCheck { IsNull = test() == null };
}
}
private void Main()
{
// test 1
var nested = new Nested();
var isNull =
NullCheck.Check( () => nested )
.ThenCheck( () => nested.Child )
.ThenCheck( () => nested.Child.Child )
.ThenCheck( () => nested.Child.Child.Child )
.ThenCheck( () => nested.Child.Child.Child.Child );
Console.WriteLine( isNull.IsNull ? "null" : "not null" );
// test 2
nested = new Nested { Child = new Nested() };
isNull = NullCheck.Check( () => nested ).ThenCheck( () => nested.Child );
Console.WriteLine( isNull.IsNull ? "null" : "not null" );
// test 3
nested = new Nested { Child = new Nested() };
isNull = NullCheck.Check( () => nested ).ThenCheck( () => nested.Child ).ThenCheck( () => nested.Child.Child );
Console.WriteLine( isNull.IsNull ? "null" : "not null" );
}
Again: you probably shouldn't use this in lieu of simple null checks due to the complexity it introduces, but it's an interesting pattern.
.NET Fiddle
As stated there is a plan to have c# 6.0 implement the ? operator to facilitate this process somewhat. If you cannot wait, I would suggest using a lambda expression and a simple helper function to solve this.
public E NestedProperty<T,E>(T Parent, Func<T,E> Path, E IfNullOrEmpty = default(E))
{
try
{
return Path(Parent);
}
catch
{
return IfNullOrEmpty;
}
}
This could be used int value = NestedProperty<First,int>(blank,f => f.Second.Third.id); as shown in the demo below
program
public class Program
{
public void Main()
{
First blank = new First();
First populated = new First(true);
//where a value exists
int value = NestedProperty<First,int>(blank,f => f.Second.Third.id);
Console.WriteLine(value);//0
//where no value exists
value = NestedProperty<First,int>(populated,f => f.Second.Third.id);
Console.WriteLine(value);//1
//where no value exists and a default was used
value = NestedProperty<First,int>(blank,f => f.Second.Third.id,-1);
Console.WriteLine(value);//-1
}
public E NestedProperty<T,E>(T Parent, Func<T,E> Path, E IfNullOrEmpty = default(E))
{
try
{
return Path(Parent);
}
catch
{
return IfNullOrEmpty;
}
}
}
simple demo structure
public class First
{
public Second Second { get; set; }
public int id { get; set; }
public First(){}
public First(bool init)
{
this.id = 1;
this.Second = new Second();
}
}
public class Second
{
public Third Third { get; set; }
public int id { get; set; }
public Second()
{
this.id = 1;
this.Third = new Third();
}
}
public class Third
{
public int id { get; set; }
public Third()
{
this.id = 1;
}
}
Since 3.5 (maybe earlier), You could write very simple extension method
public static TResult DefaultOrValue<T, TResult> (this T source,
Func<T, TResult> property) where T : class
{
return source == null ? default(TResult) : property(source);
}
You may name this method even shortier and then use like this
var instance = new First {SecondInstance = new Second
{ThirdInstance = new Third {Value = 5}}};
var val =
instance .DefaultOrValue(x => x.SecondInstance)
.DefaultOrValue(x => x.ThirdInstance)
.DefaultOrValue(x => x.Value);
Console.WriteLine(val);
Console.ReadLine();
so source classes are:
public class Third
{
public int Value;
}
public class First
{
public Second SecondInstance;
}
public class Second
{
public Third ThirdInstance;
}
I have an object lets call it ObjectA
and that object has 10 properties and those are all strings.
var myObject = new {Property1="",Property2="",Property3="",Property4="",...}
is there anyway to check to see whether all these properties are null or empty?
So any built-in method that would return true or false?
If any single of them is not null or empty then the return would be false. If all of them are empty it should return true.
The idea is I do not want to write 10 if statement to control if those properties are empty or null.
Thanks
You can do it using Reflection
bool IsAnyNullOrEmpty(object myObject)
{
foreach(PropertyInfo pi in myObject.GetType().GetProperties())
{
if(pi.PropertyType == typeof(string))
{
string value = (string)pi.GetValue(myObject);
if(string.IsNullOrEmpty(value))
{
return true;
}
}
}
return false;
}
Matthew Watson suggested an alternative using LINQ:
return myObject.GetType().GetProperties()
.Where(pi => pi.PropertyType == typeof(string))
.Select(pi => (string)pi.GetValue(myObject))
.Any(value => string.IsNullOrEmpty(value));
I suppose you want to make sure that all properties are filled in.
A better option is probably by putting this validation in the constructor of your class and throw exceptions if validation fails. That way you cannot create a class that is invalid; catch exceptions and handle them accordingly.
Fluent validation is a nice framework (http://fluentvalidation.codeplex.com) for doing the validation. Example:
public class CustomerValidator: AbstractValidator<Customer>
{
public CustomerValidator()
{
RuleFor(customer => customer.Property1).NotNull();
RuleFor(customer => customer.Property2).NotNull();
RuleFor(customer => customer.Property3).NotNull();
}
}
public class Customer
{
public Customer(string property1, string property2, string property3)
{
Property1 = property1;
Property2 = property2;
Property3 = property3;
new CustomerValidator().ValidateAndThrow();
}
public string Property1 {get; set;}
public string Property2 {get; set;}
public string Property3 {get; set;}
}
Usage:
try
{
var customer = new Customer("string1", "string", null);
// logic here
} catch (ValidationException ex)
{
// A validation error occured
}
PS - Using reflection for this kind of thing just makes your code harder to read. Using validation as shown above makes it explicitly clear what your rules are; and you can easily extend them with other rules.
The following code returns if any property is not null.
return myObject.GetType()
.GetProperties() //get all properties on object
.Select(pi => pi.GetValue(myObject)) //get value for the property
.Any(value => value != null); // Check if one of the values is not null, if so it returns true.
Here you go
var instOfA = new ObjectA();
bool isAnyPropEmpty = instOfA.GetType().GetProperties()
.Where(p => p.GetValue(instOfA) is string) // selecting only string props
.Any(p => string.IsNullOrWhiteSpace((p.GetValue(instOfA) as string)));
and here's the class
class ObjectA
{
public string A { get; set; }
public string B { get; set; }
}
A slightly different way of expressing the linq to see if all string properties of an object are non null and non empty:
public static bool AllStringPropertyValuesAreNonEmpty(object myObject)
{
var allStringPropertyValues =
from property in myObject.GetType().GetProperties()
where property.PropertyType == typeof(string) && property.CanRead
select (string) property.GetValue(myObject);
return allStringPropertyValues.All(value => !string.IsNullOrEmpty(value));
}
Note if you've got a data structural hierarchy and you want to test everything in that hierarchy, then you can use a recursive method. Here's a quick example:
static bool AnyNullOrEmpty(object obj) {
return obj == null
|| obj.ToString() == ""
|| obj.GetType().GetProperties().Any(prop => AnyNullOrEmpty(prop.GetValue(obj)));
}
To only check if all properties are null:
bool allPropertiesNull = !myObject.GetType().GetProperties().Any(prop => prop == null);
you can use reflection and extension methods to do this.
using System.Reflection;
public static class ExtensionMethods
{
public static bool StringPropertiesEmpty(this object value)
{
foreach (PropertyInfo objProp in value.GetType().GetProperties())
{
if (objProp.CanRead)
{
object val = objProp.GetValue(value, null);
if (val.GetType() == typeof(string))
{
if (val == "" || val == null)
{
return true;
}
}
}
}
return false;
}
}
then use it on any object with string properties
test obj = new test();
if (obj.StringPropertiesEmpty() == true)
{
// some of these string properties are empty or null
}
No, I don't think there is a method to do exactly that.
You'd be best writing a simple method that takes your object and returns true or false.
Alternatively, if the properties are all the same, and you just want to parse through them and find a single null or empty, perhaps some sort of collection of strings would work for you?
You can try the following query :
if the object is "referenceKey" (where few properties may be null )
referenceKey.GetType().GetProperties().Where(x => x.GetValue(referenceKey) == null)
I need to count the properties where the value is set to not Null, so I have used the following query :
var countProvidedReferenceKeys = referenceKey.GetType().GetProperties().Where(x => x.GetValue(referenceKey) != null).Count();