How to Ignore Convert to Nullable in Lambda Expressions

How to ignore convert to nullable in lambda expressions?

No, there's no way to avoid it. The operator you're calling accepts a bool?, not a bool, and so the argument must be a bool?, else it couldn't compile. There is an implicit conversion from bool to bool?, and that's seen from the convert expression. Without that implicit conversion it wouldn't be a valid expression.

You could in theory manually construct your own expression that used a true nullable boolean constant value, but there's no way to make that lambda "automatically" generate such an expression, and trying to create that new expression is almost certainly way more work than simply having your query provider handle the convert expression.

Trying to filter on a Nullable type using Expression Trees

The problem is that when generating binary expressions, the operands have to be of compatible types. If not, you need to perform a conversion on one (or both) until they are compatible.

Technically, you cannot compare a DateTime with a DateTime?, the compiler implicitly promotes one to the other which allows us to do our comparisons. Since the compiler is not the one generating the expression, we need to perform the conversion ourself.

I've tweaked your example to be more general (and working :D).

public static Expression<Func<TObject, bool>> ApplyFilter<TObject, TValue>(String filterField, FilterOperation filterOper, TValue filterValue)
{
var type = typeof(TObject);
ExpressionType operation;
if (type.GetProperty(filterField) == null && type.GetField(filterField) == null)
throw new MissingMemberException(type.Name, filterField);
if (!operationMap.TryGetValue(filterOper, out operation))
throw new ArgumentOutOfRangeException("filterOper", filterOper, "Invalid filter operation");

var parameter = Expression.Parameter(type);

var fieldAccess = Expression.PropertyOrField(parameter, filterField);
var value = Expression.Constant(filterValue, filterValue.GetType());

// let's perform the conversion only if we really need it
var converted = value.Type != fieldAccess.Type
? (Expression)Expression.Convert(value, fieldAccess.Type)
: (Expression)value;

var body = Expression.MakeBinary(operation, fieldAccess, converted);

var expr = Expression.Lambda<Func<TObject, bool>>(body, parameter);
return expr;
}

// to restrict the allowable range of operations
public enum FilterOperation
{
Equal,
NotEqual,
LessThan,
LessThanOrEqual,
GreaterThan,
GreaterThanOrEqual,
}

// we could have used reflection here instead since they have the same names
static Dictionary<FilterOperation, ExpressionType> operationMap = new Dictionary<FilterOperation, ExpressionType>
{
{ FilterOperation.Equal, ExpressionType.Equal },
{ FilterOperation.NotEqual, ExpressionType.NotEqual },
{ FilterOperation.LessThan, ExpressionType.LessThan },
{ FilterOperation.LessThanOrEqual, ExpressionType.LessThanOrEqual },
{ FilterOperation.GreaterThan, ExpressionType.GreaterThan },
{ FilterOperation.GreaterThanOrEqual, ExpressionType.GreaterThanOrEqual },
};

Then to use it:

var filterField = "DateOfBirth";
var filterOper = FilterOperation.LessThanOrEqual;
var filterValue = DateTime.Parse("2000/01/01"); // note this is an actual DateTime object

var oldFamily = ApplyFilter<Person>(filterField, filterOper, filterValue);

var query = from p in people.AsQueryable().Where(oldFamily)
select p;

I don't know if this will work as-is for all cases but it certainly works for this particular case.

Return null or something nullable from lambda in transformation mehtod WebFlux

When working in a functional/reactive world you should try to avoid all null checks and try to never return null from any methods.

Instead return Optional<T> when there is a risk for a null return, and return Mono.error when there is an error in a function that returns Mono. Or return Mono.empty if you just want to skip returning something.

By using optional you can rewrite the code to something much cleaner.

public Optional<Pojo> parseJson(String json) {
// Return an optional if there is risk for a null.
return Optional.ofNullable(new Pojo());
}

private final IdMapper idMapper = new IdMapper();
private final Repo repo = new Repo();

public Mono<Pojo> query(long id) {

// By returning an optional from the idMapper
// you can chain on and avoid null checks.
return idMapper.getValue(id).map(integer -> repo.query(integer)
.map(s -> parseJson(s).map(Mono::just)
.orElse(Mono.empty())))
.orElse(Mono.error(() -> new NotFoundException("No Pojo with ID could be found")));
}

class Pojo {
// Some pojo class
}

class Repo {
public Mono<String> query(long id) {
return Mono.just("Foo");
}
}

class IdMapper {

public Optional<Integer> getValue(long id) {
// Here return an Optional instead of null!
return Optional.of(1);
}
}

Here i return Optionals and a make some decisions to either return a Mono.empty or a Mono.error depending on what happens.

How to check for nulls in a deep lambda expression?

You can't do that in a concise way. You can either make the lambda multiple lines, or use nested ternary operators:

var result = GetValue(one, x => x.Two == null ? null :
x.Two.Three == null ? null :
x.Two.Three.Four == null ? null :
x.Two.Three.Four.Foo;

Ugly, I know.

If null then set it to empty string lambda expression in linq

If s comes null sometimes, you could use:

list.Where(s => s != null && s.GetType().GetProperty(item).GetValue(s, null).ToString().ToLower().Contains(searchString.ToLower()));

Later edit

So the problem is that GetValue returns null. In this case, you can use the null-coalescing operator ??. I would personally expand the expression so it's easier to read:

list.Where(s => 
{
var property = s.GetType().GetProperty(item);
var value = property.GetValue(s, null);
if (value == null) return false;

return value.ToString().Contains(searchString, StringComparison.OrdinalIgnoreCase);
});

Working with nullable types in Expression Trees

I had to convert the value type to the column type using Expression.Convert:

Expression where = Expression.GreaterThanOrEqual(column, Expression.Convert(Expression.Constant(value), column.Type));

Ignore Null and Empty string match in Linq Query

You could add && (string.IsNullOrEmpty(o.MulDivFlg) != string.IsNullOrEmpty(lstExchgMatch[0].MulDivFlg)) condition in your Any lambda expression:

var tMisMatchList = lstExchgMatch.Any(o => o.MulDivFlg != lstExchgMatch[0].MulDivFlg &&
(string.IsNullOrEmpty(o.MulDivFlg) != string.IsNullOrEmpty(lstExchgMatch[0].MulDivFlg)));

Trying to assign value to nullable Guid property using an expression

Not quite sure why you need to assign airflowLab.SourceOfData.Id to the explicit FK property SourceOfDataId, since in the context of server side LINQ to Entities it should be the same as assigning directly airflowLab.SourceOfDataId.

But let say for some reason you need that. Since the static type of the airflowLab.SourceOfData.Id expression is non nullable Guid (C# has no notion of implicit null propagation), the actual expression emitted by the C# compiler for

SourceOfDataId = airflowLab.SourceOfData.Id

would be

SourceOfDataId = (Guid?)airflowLab.SourceOfData.Id

Note the cast to nullable Guid. In Expression terms that maps to Expression.Convert, so what you need is something like

Expression.Convert(
Expression.Property(Expression.Property(itemParam, "SourceOfData"), "Id"),
typeof(Guid?))

Java 8 lambda comparator with null value check

There are default implementations within Comparator you can use: nullsFirst or nullsLast:

Comparator.comparing(YourObject::getStartDate, 
Comparator.nullsFirst(Comparator.naturalOrder())
)


Related Topics



Leave a reply



Submit