An expression tree lambda may not contain a null propagating operator
The example you were quoting from uses LINQ to Objects, where the implicit lambda expressions in the query are converted into delegates... whereas you're using EF or similar, with IQueryable<T>
queryies, where the lambda expressions are converted into expression trees. Expression trees don't support the null conditional operator (or tuples).
Just do it the old way:
price = co == null ? 0 : (co.price ?? 0)
(I believe the null-coalescing operator is fine in an expression tree.)
Error: An expression tree lambda may not contain a null propagating operator for Linq with from
This is a weird rule of LINQ. The problem is in the expression:
InspectedCompanyName = (from a in contacts where a.ContactId == r.InspectedCompanyDataId select a.FirstName)?.FirstOrDefault()
which is inside your select. ?.
is not allowed.
Thankfully, ?:
(the ternary operator/inline conditional) is allowed, so this can be rewritten. For convenience you need a let:
myOrphanList =
(
from v in allViolations
from r in allInspectionResults
from i in allItems
where
r.InspectionResultId == i.InspectionResultId &&
i.InspectionItemId == v.InspectionItemId
let firstName = from a in contacts // Pop your sub-query in a variable here
where a.ContactId == r.InspectedCompanyDataId
select a.FirstName
select new OrphanViolationsReport
{
ViolationId = v.ViolationId,
ViolationNumber = v.ViolationNumber,
ViolationDate = v.ViolationDate,
ViolationType = v.ViolationType.ViolationTypeCode,
ItemYear = i.ItemYear,
ItemMakeManufacturer = i.ItemMakeManufacturer,
ItemModel = i.ItemModel,
VIN = i.VIN,
PIN = i.PIN,
InspectionResultId = r.InspectionResultId,
InspectionResultNumber = r.InspectionRequestNumber,
DealerDmvNumber = r.DealerDmvNumber,
// USe ternary operator here
InspectedCompanyName = firstName == null ? null : firstName
}
).ToList();
This is too complex for me to test compile, but that's basically the idea.
That said, as @SalahAkbari points out, the logic here is very strange. A select query (the one I've put into firstName
) will never return null
, it will return an empty collection, so what's the point?
Automapper 8 - An expression tree lambda may not contain a null propagating operator
New Func
-based overloads in Automapper 8.0.0 accept more parameters compared to old/removed ResolveUsing
overloads.
Instead of using lambda expression with single input parameter opt.MapFrom(src => ...)
when replacing ResolveUsing
, overload with 2 parameters should be used opt.MapFrom((src, dest) => ...)
.
MapFrom
expression becomes:
opt => opt.MapFrom((src, dest) => src?.Customer ?? new Customer())
Full example:
CreateMap<SourceType, DestinationType>()
.ForMember(dest => dest.Customer,
opt => opt.MapFrom((src, dest) => src?.Customer ?? new Customer())
);
Why can't I use the null propagation operator in lambda expressions?
It's complicated since expression tree lambdas (unlike delegate lambdas) are interpreted by already existing LINQ providers which don't yet support null propagating.
Converting to a conditional expression is not always accurate as there are multiple evaluations while with ?.
there's only a single evaluation for example:
customer.Where(a => c.Increment()?.Name) // Written by the user
customer.Where(a => c.Increment() == null ? null : c.Increment().Name) // Incorrectly interpreted by an old LINQ provider
You can go deeper in the relevant discussion on CodePlex where 3 solutions are offered: NullPropagationExpression
, ConditionalExpression
& a hybrid
Expression Tree for o?.Value
Normally, if you want to know how to construct an expression tree for some expression, you let the C# compiler do it and inspect the result.
But in this case, it won't work, because "An expression tree lambda may not contain a null propagating operator." But you don't actually need the null propagating operator, you just need something that behaves like one.
You can do that by creating an expression that looks like this: o == null ? null : o.Value
. In code:
public Expression CreateNullPropagationExpression(Expression o, string property)
{
Expression propertyAccess = Expression.Property(o, property);
var propertyType = propertyAccess.Type;
if (propertyType.IsValueType && Nullable.GetUnderlyingType(propertyType) == null)
propertyAccess = Expression.Convert(
propertyAccess, typeof(Nullable<>).MakeGenericType(propertyType));
var nullResult = Expression.Default(propertyAccess.Type);
var condition = Expression.Equal(o, Expression.Constant(null, o.Type));
return Expression.Condition(condition, nullResult, propertyAccess);
}
Test Null after FirstOrDefault
Select the Name of the ProductType that you want before your FirstOrDefault:
Name = product.ProductType.ProductTypesI18N
.Where(productType => productType.LanguageCode == languageCode)
.Select(productType => productType.Name)
.FirstOrDefault(),
Simple comme bonjour!
What is a correct way to select a property of optional navigation property in Entity Framework?
Why not use a conditional operator?
CaseRelationTypeName = (rc.CasesRelationType != null) ? rc.CasesRealtionType.Name : null;
Related Topics
How to Export a Gridview.Datasource to a Datatable or Dataset
Datagridview Checkbox Column - Value and Functionality
How to Concatenate Two System.Io.Stream Instances into One
Create Object Instance of a Class Having Its Name in String Variable
Does Reactive Extensions Support Rolling Buffers
Sorting an Array of Folder Names Like Windows Explorer (Numerically and Alphabetically) - Vb.Net
Avoiding Null Reference Exceptions
Why Doesn't the Xmlserializer Need the Type to Be Marked [Serializable]
Why Is List When Passed Without Ref to a Function Acting Like Passed with Ref
Combine Two Images into One New Image
Unity3D Ui, Calculation for Position Dragging an Item
How to Convert String to Integer in C#
How to Disable Cascade Delete for Link Tables in Ef Code-First
Itextsharp - How to Get the Position of Word on a Page
How to Run External Program via a C# Program
How to Retrieve a List of Parameters from a Stored Procedure in SQL Server