У меня есть класс представляет общий объект ФильтрующегоОбработки NULLABLE ссылки при построении LambdaExpression динамически
public class Filter
{
public string column { get; set; }
public string operator { get; set; }
public string data { get; set; }
}
, что я могу превратить в течение LambdaExpression
благодаря коду, как этот
public LambdaExpression ToExpression(IQueryable query) {
LambdaExpression toReturn = null;
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = GetMemberExpression(column, parameter);
ConstantExpression filter = Expression.Constant(Convert.ChangeType(data, memberAccess.Type));
WhereOperation condition = (WhereOperation)StringEnum.Parse(typeof(WhereOperation), operator);
LambdaExpression lambda = BuildLambdaExpression(memberAccess, filter, parameter, condition, data);
if (toReturn == null) {
toReturn = lambda;
}
return toReturn;
}
согласно требование Filter
член column
может содержать своего рода навигационный синтакс для запросов полей, который выражается как FieldA.FieldB.Description
, что переводит на:
- Получить значение типа Т возвращаемое из свойства
- FieldA Получить значение типа T1 возвращается из FieldB Т
- Получить значение типа Т2 возвращается из описания T2
в результате лямбда, как этот: p.FieldA.FieldB.Description == "data"
и я могу использовать этот результат в качестве параметра метода Where
расширения любого IQueryable
Проблема возникает, когда один из членов навигационного запроса - тип Nullable
. В этом случае, если предположить, FieldA обнуляемый, правильный лямбда должен быть
p.FieldA != null && p.FieldA.FieldB.Description == "data"
Я пытался осуществить эту проверку при построении MemberExpression
объекта, используя код как этого
MemberExpression memberAccess = null;
foreach (var property in column.Split('.')) {
memberAccess = MemberExpression.Property(memberAccess ?? (p as Expression), property);
Type memberType = memberAccess.Type;
if (memberType.IsGenericType &&
memberType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
//Create here an expression of type : memberAccess != null
}
}
, что хорошо для примитивных типов, но не работает, например, с другими объектными ссылками, например EF EntityReference
экземплярами объектов. Я знаю, что я мог бы просто добавить еще одно условие к предыдущему if
как
if ((memberType.IsGenericType &&
memberType.GetGenericTypeDefinition() == typeof(Nullable<>)) ||
memberType.IsClass) {
}
но мне кажется, слишком много общего производства лямбда слишком много условий и большинство из них может быть неполезным.
Есть ли способ улучшить индивидуализацию ссылок на NULL?
Если выражение предназначено для Entity Framework, я бы не стал беспокоиться. 'p.FieldA.FieldB.Description ==" data "' просто будет ложным без каких-либо исключений, если 'FieldA' или' FieldB' равно null. Если это предназначено для компиляции и запуска в памяти, это еще одна история. –
Я использую первый выпуск EF, тот, который работает с .NET 3.5. Если я делаю запрос, как в примере, запрос просто не применяется, и результат подобен тому, как я бы не указал какой-либо фильтр ... – Lorenzo