Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert my value type to nullable equivalent

I have an ad-hoc reporting system; I have no compile-time knowledge of the source type of queries or of the required fields. I could write expression trees at runtime using the System.Linq.Expressions.Expression factory methods, and invoke LINQ methods using reflection, but Dynamic LINQ is a simpler solution.

The reporting system is to allow for queries which returns the result of a LEFT JOIN. There are fields in the joined table which are NOT NULL in the database; but because this is a LEFT JOIN, those fields will contain NULL for certain records. The EF6-generated expression falls on this, because the expression projects to a non-nullable value type.

If I was doing this in compile-time LINQ, I would explicitly cast to the nullable type:

enum Color { Red, Green,  Blue }

// using System;
// using static System.Linq.Enumerable;
// using System.Linq;

var range = Range(0, 3).Select(x => (Color)x).AsQueryable();
var qry = range.Select(x => (Color?)x);

Dynamic LINQ supports explicit conversions:

// using static System.Linq.Dynamic.Core

var qry1 = range.Select("int?(it)");

but only a specific set of types can be referenced in the query. If I try to use Color in the query:

var qry2 = range.Select("Color(it)");

I get the following error:

No applicable method 'Color' exists in type 'Color'

and if I try to explicitly cast to Color?:

var qry3 = range.Select("Color?(it)");

I get:

Requested value 'Color' was not found.

How can I do this using the Dynamic LINQ library?

like image 496
Zev Spitz Avatar asked Mar 15 '20 11:03

Zev Spitz


People also ask

How to declare nullable in C#?

You can declare nullable types using Nullable<t> where T is a type. Nullable<int> i = null; A nullable type can represent the correct range of values for its underlying value type, plus an additional null value. For example, Nullable<int> can be assigned any value from -2147483648 to 2147483647, or a null value.

What is a nullable value?

You typically use a nullable value type when you need to represent the undefined value of an underlying value type. For example, a Boolean, or bool , variable can only be either true or false . However, in some applications a variable value can be undefined or missing.

What does nullable mean in C#?

By Hemant Manwani. Nullable is a term in C# that allows an extra value null to be owned by a form.

What is the default value of nullable int C#?

The default value of a bool variable in C# is false (reference). Therefore, the HasValue property of a default Nullable<T> instance is false ; which in turn makes that Nullable<T> instance itself act like null .


2 Answers

Dynamic LINQ provides a Cast method which can be used as follows:

var range = Enumerable.Range(0,3).Select(x => (Color)x).AsQueryable();
var castDynamic = range.Cast(typeof(Color?)).ToDynamicArray();
castDynamic.Dump();

You can also pass a string with the name of the output type. Note that for nullable types, you need the full name of the type:

string s = typeof(Color?).FullName;
s.Dump();
var castDynamicFromString = range.Cast(s);
castDynamicFromString.Dump();

Cast can also be used within the Dynamic LINQ string expression, either passing in a Type object as a parameter, or by using the name directly:

var castInSelect = range.Select($@"Cast(""{s}""").ToDynamicArray();
castInSelect.Dump();

Output in LINQPad:

enter image description here

like image 170
Stef Heyenrath Avatar answered Sep 29 '22 23:09

Stef Heyenrath


Try this:

var arg0 = Expression.Parameter(typeof(Color), "x");
var expr = DynamicExpressionParser.ParseLambda(new[] { arg0 }, typeof(Color?), "x");
var qry2 = range.AsQueryable().Select("@0(it)", expr);

Also see https://github.com/StefH/System.Linq.Dynamic.Core/wiki/Dynamic-Expressions#dynamic-lambda-invocation

like image 43
weichch Avatar answered Sep 29 '22 21:09

weichch