Good way to handle NullReferenceException before C# 6.0 - c#

My code below gives me a NullReferenceException and the stack trace tells me the problem is in the Count method, so I'm pretty sure at some point foo, bar or baz is null.
My code:
IQueryable<IGrouping<string, Referral>> queryable= ...;
var dict = queryable.ToDictionary(g => g.Key.ToString(),
g => g.Count(r => r.foo.bar.baz.dummy == "Success"));
I'm wondering what's a concise way to handle null cases.
I learn that in C# 6.0 I can just do foo?.bar?.baz?.dummy, however the project I'm working on isn't C# 6.0

A solution for <6.0 would be:
.Count(r => r.foo != null &&
r.foo.bar != null &&
r.foo.bar.baz != null &&
r.foo.bar.baz.dummy == "Success")
Exactly for complex constructs like the one above the null propagation operator was introduced.
Furthermore you could also refactor the expression into a private method:
private Expression<Func<Referral, bool>> Filter(string value)
{
return r => r.foo != null &&
r.foo.bar != null &&
r.foo.bar.baz != null &&
r.foo.bar.baz.dummy == value;
}
and use it as follows:
g => g.Count(Filter("Success"))

You can use the following extension methods.
public static TResult With<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator)
where TResult : class
where TInput : class
{
return o == null ? null : evaluator(o);
}
public static TResult Return<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator, TResult failureValue)
where TInput : class
{
return o == null ? failureValue : evaluator(o);
}
Their combination gives you a nice, readable API for handling nulls:
return foo
.With(o => o.bar)
.With(o => o.baz)
.Return(o => o.dummy, null);

The problem is that the ToDictionary method isn't actually done on the queryable - instead, you get the whole collection, and do the aggregation in your application, rather than on the DB server.
So instead of using ToDictionary directly, use Select first:
IQueryable<IGrouping<string, Referral>> queryable= ...;
var dict = queryable.Select(g => new { Key = g.Key.ToString(),
Count = g.Count(r => r.foo.bar.baz.dummy == "Success") })
.ToDictionary(i => i.Key, i => i.Count);
This will make sure the aggregation is done in the database (where you don't care about those nulls) and not in the C# code (where you get a NullReferenceException).
Of course, this assumes that the queryable you're using is a DB query (or, to be more precise, a queryable that supports aggregation and has ANSI SQL-like NULL semantics). If you have a different custom queryable, it's not going to help (unless you explicitly add those NULL semantics yourself).

// if null, use null
if(objectvariable == null)
{
// throw exception
}
// if not null
if(objectvariable != null)
{
// continue
}

Related

Use WhereIf for multiple condition in c#

Hi can someone help me how best we can use whereif in LINQ, here I have a code which works fine, but I want to convert this query with WhereIf.
public async Task LoadQuery(IEnumerable<string> codes)
{
var query = _dBContext.QueryTable.Where(x => !x.InActive).AsQueryable();
if (codes!= null && codes.Any())
query = query.Where(x => codes.Contains(x.FirstCode) || query.Contains(x.SecondCode));
else
query = query.Where(x => !x.HasException.HasValue);
var data = query.ToList();
}
I have tried it with WhereIF ienumerable but not succeed. Here is the link which I followed.
https://extensionmethod.net/csharp/ienumerable-t/whereif
WhereIf isn't really suitable for your case, for 2 reasons:
You're calling two different functions on your if-else, while WhereIf is built to accept a single function (predicate) to be executed if some condition is satisfied.
WhereIf is an extension method for IEnumerable<TSource>, while your'e trying to use it as an extension method for IQueryable<TSource>.
If you insist, you'd have to define an extension method for IQueryable<TSource>, and in doing so, just define it as WhereIfElse:
public static class ExtensionMethods
{
public static IQueryable<TSource> WhereIfElse<TSource>(this IQueryable<TSource> source, bool condition, Func<TSource, bool> predicateIf, Func<TSource, bool> predicateElse)
{
if (condition)
return source.Where(predicateIf).AsQueryable();
else
return source.Where(predicateElse).AsQueryable();
}
}
So, let's say that query's type is IQueryable<Item> (replace Item with your actual type):
public async Task<List<Item>> LoadQuery(IEnumerable<string> codes)
{
var query = _dBContext.QueryTable.Where(x => !x.InActive).AsQueryable();
query = query.WhereIfElse(
// condition
codes != null && codes.Any(),
// predicateIf
(Item x) => codes.Contains(x.FirstCode) || codes.Contains(x.SecondCode),
// predicateElse
(Item x) => !x.HasException.HasValue
);
var data = query.ToList();
return data;
}
P.S. note I changed your return value, though there still isn't an await.
bool condition = codes!= null && codes.Any();
var data = _dBContext.QueryTable
.WhereIf(condition, a=> codes.Contains(a.FirstCode) || codes.Contains(a.SecondCode))
.WhereIf(!condition, a=> !a.HasException.HasValue && !a.InActive).ToList();

Complex edit of a body Expression<Func<T,bool>>

Summary: I want to know how can I detect specific definitions from the expression's body then change it in the way I want, such as
e.Entity.ListA.Union(e.ListB).Any(...)...
To
e.Entity != null &&
((e.Entity.ListA != null && e.Entity.ListA.Any(...))
|| (e.Entity.ListB != null && e.Entity.ListB.Any(...)))
Only using Linq Expression techniques as I see it is the ideal solution
As a part of writing a clean C# code, I have written a set of predefined expressions and using LinqKit extensions I can combine between them, hence it will extend the dynamism of writing complex expressions easily, until that everything is okay. In addition, I want to use them to filter both IQuerable and IEnumerable cases. However, as you know, there are some cases where the defined expression will not work in the Former or the latter, I successfully have avoided a lot of such problems. Until I came to the case where I made a solution but I am still feeling is not the ideal.
I will first start by showing the problem, then explain the wished solution, in the end, I will share my attempt.
//---
public class AssignmentsEx : BaseEx
{
//.........
/// <summary>
/// (e.FreeRoles AND e.RoleClass.Roles) ⊆ ass.AllRoles
/// </summary>
public static Expression<Func<T, bool>> RolesInclosedBy<T>(IAssignedInstitution assignedInstitution) where T : class, IAssignedInstitution
{
var allStaticRoles = AppRolesStaticData.AdminRolesStr.GetAll();
var assAllRoles = assignedInstitution.AllRoles.Select(s => s.Name).ToList();
var hasAllRoles = allStaticRoles.All(assR => assAllRoles.Any(sR => sR == assR));
if (hasAllRoles)
return e => true;
// for LINQ to SQL the expression works perfectly as you know
// the expression will be translated to an SQL code
// for IEnumerable case the nested object Roles with throw null obj ref
// exception if the RoleClass is null (and this is a healthy case from code execution
//
return Expression<Func<T, bool>> whenToEntity = e => e.FreeRoles.Union(e.RoleClass.Roles).All(eR => assAllRoles.Any(assR => assR == eR.Name));
}
//.........
}
As you see If I use this method to define a list of objects with RoleClass is null or FreeRoles is null it will throw a NullException.
-- the best-expected suggestion I think it will play on three factors:
possibility to detect the desired fragment from the expression body
modify the fragment to be as needed for the IEnumerable case or vice versa
reconstruct and return new expression
this way will help me to keep the method static and modify it via extension method: e.g. ex.WithSplittedUnion()
rather than the traditional way i.e. I am using now as follow
public class AssignmentsEx
{
public LinqExpressionPurpose purpose{get;}
public AssignmentsEx(LinqExpressionPurpose purpose) : base(purpose)
{
Purpose = purpose
}
public Expression<Func<T, bool>> RolesInclosedBy<T>(IAssignedInstitution assignedInstitution) where T : class, IAssignedInstitution
{
var allStaticRoles = AppRolesStaticData.AdminRolesStr.GetAll();
var assAllRoles = assignedInstitution.AllRoles.Select(s => s.Name).ToList();
var hasAllRoles = allStaticRoles.All(assR => assAllRoles.Any(sR => sR == assR));
if (hasAllRoles)
return e => true;
Expression<Func<T, bool>> whenToObject = e => (e.FreeRoles == null || e.FreeRoles.All(eR => assAllRoles.Any(assR => assR == eR.Name)))
&& (e.RoleClass == null || e.RoleClass.Roles == null || e.RoleClass.Roles.All(eR => assAllRoles.Any(assR => assR == eR.Name)));
Expression<Func<T, bool>> whenToEntity = e => e.FreeRoles.Union(e.RoleClass.Roles).All(eR => assAllRoles.Any(assR => assR == eR.Name));
return Purpose switch
{
LinqExpressionPurpose.ToEntity => whenToEntity,
LinqExpressionPurpose.ToObject => whenToObject,
_ => null,
};
}
}
I hope the explaination is clear, Thanks in advance
From how I see it, what you need is ExpressionVisitor to traverse and modify ExpressionTree. One thing I would change is the way you call Any.
Instead of
e.Entity != null &&
((e.Entity.ListA != null && e.Entity.ListA.Any(...))
|| (e.Entity.ListB != null && e.Entity.ListB.Any(...)))
I'd go for
(
e.Entity != null && e.Entity.ListA != null && e.Entity.ListB != null
? e.Entity.ListA.Union(e.Entity.ListB)
: e.Entity != null && e.Entity.ListA != null
? e.Entity.ListA
: e.Entity.ListB != null
? e.Entity.ListB
: new Entity[0]
).Any(...)
I find it easier to construct ExpressionTree and the outcome will be the same.
Example code:
public class OptionalCallFix : ExpressionVisitor
{
private readonly List<Expression> _conditionalExpressions = new List<Expression>();
private readonly Type _contextType;
private readonly Type _entityType;
private OptionalCallFix(Type contextType, Type entityType)
{
this._contextType = contextType;
this._entityType = entityType;
}
protected override Expression VisitMethodCall(MethodCallExpression node)
{
// Replace Queryable.Union(left, right) call with:
// left == null && right == null ? new Entity[0] : (left == null ? right : (right == null ? left : Queryable.Union(left, right)))
if (node.Method.DeclaringType == typeof(Queryable) && node.Method.Name == nameof(Queryable.Union))
{
Expression left = this.Visit(node.Arguments[0]);
Expression right = this.Visit(node.Arguments[1]);
// left == null
Expression leftIsNull = Expression.Equal(left, Expression.Constant(null, left.Type));
// right == null
Expression rightIsNull = Expression.Equal(right, Expression.Constant(null, right.Type));
// new Entity[0].AsQueryable()
Expression emptyArray = Expression.Call
(
typeof(Queryable),
nameof(Queryable.AsQueryable),
new [] { this._entityType },
Expression.NewArrayInit(this._entityType, new Expression[0])
);
// left == null && right == null ? new Entity[0] : (left == null ? right : (right == null ? left : Queryable.Union(left, right)))
return Expression.Condition
(
Expression.AndAlso(leftIsNull, rightIsNull),
emptyArray,
Expression.Condition
(
leftIsNull,
right,
Expression.Condition
(
rightIsNull,
left,
Expression.Call
(
typeof(Queryable),
nameof(Queryable.Union),
new [] { this._entityType },
left,
Expression.Convert(right, typeof(IEnumerable<>).MakeGenericType(this._entityType))
)
)
)
);
}
return base.VisitMethodCall(node);
}
protected override Expression VisitMember(MemberExpression node)
{
Expression expression = this.Visit(node.Expression);
// Check if expression should be fixed
if (this._conditionalExpressions.Contains(expression))
{
// replace e.XXX with e == null ? null : e.XXX
ConditionalExpression condition = Expression.Condition
(
Expression.Equal(expression, Expression.Constant(null, expression.Type)),
Expression.Constant(null, node.Type),
Expression.MakeMemberAccess(expression, node.Member)
);
// Add fixed expression to the _conditionalExpressions list
this._conditionalExpressions.Add(condition);
return condition;
}
return base.VisitMember(node);
}
protected override Expression VisitParameter(ParameterExpression node)
{
if (node.Type == this._contextType)
{
// Add ParameterExpression to the _conditionalExpressions list
// It is used in VisitMember method to check if expression should be fixed this way
this._conditionalExpressions.Add(node);
}
return base.VisitParameter(node);
}
public static IQueryable<TEntity> Fix<TContext, TEntity>(TContext context, in Expression<Func<TContext, IQueryable<TEntity>>> method)
{
return ((Expression<Func<TContext, IQueryable<TEntity>>>)new OptionalCallFix(typeof(TContext), typeof(TEntity)).Visit(method)).Compile().Invoke(context);
}
}
You can call it like this:
OptionalCallFix.Fix(context, ctx => ctx.Entity.ListA.Union(ctx.ListB));

C# How to pass a variable into a func?

Simple version
var myVar = some object;
myList.Where(element => myVar != null && element.Name == myVar.Name)
What I want to write
public static (Return Value) Start<T>(this T input, Func<(IDK what goes here)> exp)
{
var theVar = somehow get the myVar that was passed in;
if (theVar != null)
{
apply exp; <= I can do this part
}
}
myList.Start((myVar, element) => element.Name == myVar.Name));
Basically be able to write an expression without having to check for the null every single time.
Use anonymous lambda (I think without testing) >
myList.Start((myVar, () => element) => element.Name == myVar.Name));
I found a way, i wrote a class BaseExtension it doesn't have a lot in it, just a holder for some properties
public static BaseExtension<T> Start<T, TValue>(this IQueryable<T> input, TValue value, Func<TValue, Expression<Func<T, bool>>> expression) =>
new BaseExtension<T>(input, value == null ? null : expression.Invoke(value));
this allows me to write
_context.MyEntities.Start(myVar, value => entity => entity.Id.ToString() == myVar)
and passing in myVar allows me to do c# logic behind the scenes before the query would be executed in the database.
An example would be myVar != null or I can add a custom function that would apply the expression or not
The where method expected a Boolean type, you can use this
private static <type> <name>(<type> arg)
{
return true;
}
If this not work for you, on Visual Studio, writing something insidere where, and press ctrl + . .
See the sugested implementations

How to deal with null linq query result?

I have a linq query in which i am getting the user list and after that we are getting the record by userid filter.
var user = UserDal.GetAllUsers().First(n => n.UsersID == 1);
But what should do if GetAllUsers() function returns null ? Should we check it by applying Any() ? Or something else ?
But what should do if GetAllUsers() function returns null ?
If UserDal.GetAllUsers returns null, then you can't use Any, you will have to check it against null. You can only use Any or FirstOrDefault if the method returns a collection (even empty).
If the method could return null then:
var temp = UserDal.GetAllUsers();
if(temp != null)
{
var user = temp.FirstOrDefault(n=> n.UserID == 1);
}
If your method could return an empty collection instead of null then you can do:
var user = UserDal.GetAllUsers().FirstOrDefault(n => n.UsersID == 1);
You should modify your method UserDal.GetAllUsers to not return a null. If there are no records then an empty collection should be returned.
Why not simply check if it is null?
var users = UserDal.GetAllUsers();
if (users == null || !users.Any())
{
// handle error
}
var user = users.First(x => x.Id == someId);
However, if you're in control of the code-base, I'd certainly say that you should make it so GetAllUsers never returns null.
You could use [DefaultIfEmpty] and use that instance as default value: to handle null value
You could use Monads, e.g. https://github.com/sergun/monads.net
Or you could implement your own extension methods.
This code is adapted from the original extension method and returns default(T) instead of throwing an exception.
// UserDal.GetAllUsers() returns null and user is null
var user = UserDal.GetAllUsers().MyFirstOrDefault(n => n.UsersID == 1);
public static class IEnumerableExtensions
{
public static T MyFirstOrDefault<T>(this IEnumerable<T> source,
Func<T, bool> predicate)
{
if (source == null) return default(T);
if (predicate == null) return default(T);
foreach (T element in source)
{
if (predicate(element)) return element;
}
return default(T);
}
}
Or you could use null checks or ensure never to return null to safeguard against null reference exception when using the standard extension methods.

Check if property is null in lambda expression

I have a list of objects that I am trying to bind to a listview. I am sorting by two properties. The problem exists whereby some records may not have one of the properties. This is causing an error. I would like it to still bind the records that have the property.
IEnumerable<ERec> list = retailerList.Cast<ERec>();
lvwRetailStores.DataSource = list.OrderByDescending(r => r.Properties["RS_Partner Type"].ToString())
.ThenBy(r => r.Properties["RS_Title"].ToString());
list.Where(r => r.Properties["RS_Partner_Type"] != null && r.Properties["RS_Title"] != null)
.OrderByDescending(r => r.Properties["RS_Partner Type"].ToString())
.ThenBy(r => r.Properties["RS_Title"].ToString());
Or instead of != null, use whatever test the Properties collection has.
I've found that the ?? Operator works well. I use Parenthesis to evaluate for null,
For Example:
Datetime? Today = DateTimeValue
// Check for Null, if Null put Today's date
datetime GoodDate = Today ?? DateTime.Now
This same logic works in Lambda, just use parenthesis to ensure that the correct comparisons are used.
You can use a ternary expression in the lambda:
list.OrderByDescending(r => r.Properties["RS_Partner_Type"] == null ? null : r.Properties["RS_Partner Type"].ToString())
.ThenBy(r => r.Properties["RS_Title"] == null ? null : r.Properties["RS_Title"].ToString());
Another common approach is to give the collection a suitable default value, and return that when the collection doesn't have a particular key. For instance, if Properties implements IDictionary,
public static class IDictionaryExtension {
public static TValue GetValue<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key, TValue default) {
TValue result;
return dict.TryGetValue(key, out result) ? result : dflt;
}
}
...
lvwRetailStores.DataSource = list.OrderByDescending(r => r.GetValue("RS_Partner Type", "").ToString())
.ThenBy(r => r.GetValue("RS_Title","").ToString());

Categories