我正在动态使用动态linq来生成一些请求。
除非类为null,否则一切都很好。我得到了NullException
。
所以,我想做同样的事情:
dossiers = dossiers.Where(d => d != null && d.Demandeurs != null &&
d.Demandeurs.Any(DossierTiers => DossierTiers != null &&
DossierTiers.Tiers != null && DossierTiers.Tiers.TiersLiesEnfantsActifs != null &&
DossierTiers.Tiers.TiersLiesEnfantsActifs.Any(TiersLie => TiersLie != null && TiersLie.TiersEnfant != null &&
TiersLie.TiersEnfant.AdressePrincipale != null && TiersLie.TiersEnfant.AdressePrincipale.Adresse != null &&
TiersLie.TiersEnfant.AdressePrincipale.Adresse.CodePostal.StartsWith("45")))).ToList();
我不知道如何查看null
。
答案 0 :(得分:1)
你在那里缺少一个单一的检查然后应该没问题:TiersLie.TiersEnfant.AdressePrincipale.Adresse.CodePostal!= null。因此:
dossiers = dossiers.Where(d => d != null && d.Demandeurs != null &&
d.Demandeurs.Any(DossierTiers => DossierTiers != null &&
DossierTiers.Tiers != null && DossierTiers.Tiers.TiersLiesEnfantsActifs != null &&
DossierTiers.Tiers.TiersLiesEnfantsActifs.Any(TiersLie => TiersLie != null && TiersLie.TiersEnfant != null &&
TiersLie.TiersEnfant.AdressePrincipale != null && TiersLie.TiersEnfant.AdressePrincipale.Adresse != null &&
TiersLie.TiersEnfant.AdressePrincipale.Adresse.CodePostal != null && TiersLie.TiersEnfant.AdressePrincipale.Adresse.CodePostal.StartsWith("45")))).ToList();
由于你有很多!= null检查,最好将它们减少到必要的数量。检查d => d != null
作为示例应该不需要,因为它的null无论如何都不应该出现,因为元素不存在(对于任何(a=> a != null
构造都是相同的。这些元素不应该“出现“无论如何它们都不存在。在答案中我仍然允许它,以便我所做的代码更改只是让你的程序运行所需的最小化。
编辑:考虑原始命令(在评论中提到):
dossiers = dossiers.Where(d =>
d.Defendeurs.Any(DossierTiers => DossierTiers.Tiers != null &&
DossierTiers.Tiers.TiersLiesEnfantsActifs != null &&
DossierTiers.Tiers.TiersLiesEnfantsActifs.Any(
TiersLie => TiersLie.TiersEnfant != null &&
TiersLie.TiersEnfant.AdressePrincipale != null &&
TiersLie.TiersEnfant.AdressePrincipale.Adresse.CodePostal != null &&
TiersLie.TiersEnfant.AdressePrincipale.Adresse.CodePostal.Contains("45"))))
.ToList();
答案 1 :(得分:1)
我支持这样的评论,即你的模型应该被设计为避免空值 - 通过将成员集合初始化为空集合而不是将它们默认为null。但是,如果这不是一个选项,你应该将你的空检查逻辑提取到一个单独的方法中,我将猜测它自己重复,这些方法可以使主句更加可重复。
public bool IsValidDossier(Dossier d)
{
return d != null
&& d.Defendeurs.Any(DossierTiers =>
DossierTiers.Tiers != null
&& DossierTiers.Tiers.TiersLiesEnfantsActifs != null
&& DossierTiers.Tiers.TiersLiesEnfantsActifs.Any(TiersLie =>
TiersLie.TiersEnfant != null
&& TiersLie.TiersEnfant.AdressePrincipale != null
&& TiersLie.TiersEnfant.AdressePrincipale.Adresse.CodePostal != null;
}
public bool DossierMatchesPostalCode(Dossier d, string codePostal)
{
return d.Defendeurs.Any(dt => dt.Tiers.TiersLiesEnfantsActifs.Any(tl => tl.TiersEnfant.AdressePriincipal.Adresse.CodePostal.Contains(codePostal);
}
在主代码中,您可以重复使用它:
var relevantDossiers =
dossier.Where(d => IsValidDossier(d) && DossierMatchesPostalCode(d, "45"));
答案 2 :(得分:0)
这是我的功能(基于Web上的某些功能),用于生成动态linq:
public static Expression GetExpression(Expression parameter, object Operator, object value, params string[] properties)
{
Expression resultExpression = null;
Expression childParameter, navigationPropertyPredicate;
Type childType = null;
if (properties.Count() > 1)
{
parameter = Expression.Property(parameter, properties[0]);
var isCollection = typeof(IEnumerable).IsAssignableFrom(parameter.Type);
if (isCollection)
{
childType = parameter.Type.GetGenericArguments()[0];
childParameter = Expression.Parameter(childType, childType.Name);
}
else
{
childParameter = parameter;
}
var innerProperties = properties.Skip(1).ToArray();
navigationPropertyPredicate = GetExpression(childParameter, Operator, value, innerProperties);
if (isCollection)
{
var anyMethod = typeof(Enumerable).GetMethods().Single(m => m.Name == "Any" && m.GetParameters().Length == 2);
anyMethod = anyMethod.MakeGenericMethod(childType);
navigationPropertyPredicate = Expression.Call(anyMethod, parameter, navigationPropertyPredicate);
resultExpression = BuildLambda(parameter, navigationPropertyPredicate);
}
else
{
resultExpression = navigationPropertyPredicate;
}
}
else
{
ConstantExpression right = null;
var childProperty = parameter.Type.GetProperty(properties[0]);
var left = Expression.Property(parameter, childProperty);
right = (value != null) ? right = Expression.Constant(value, value.GetType()) : Expression.Constant(string.Empty);
navigationPropertyPredicate = GetExpression(left, right, Operator);
resultExpression = BuildLambda(parameter, navigationPropertyPredicate);
}
return resultExpression;
}
private static Expression GetExpression(MemberExpression left, ConstantExpression right, Object p)
{
MethodInfo c = null;
if (p is OperatorUsedWithString)
{
switch ((OperatorUsedWithString)p)
{
case OperatorUsedWithString.CommencePar:
c = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
return Expression.Call(left, c, right);
case OperatorUsedWithString.Contient:
c = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
return Expression.Call(left, c, right);
case OperatorUsedWithString.TerminePar:
c = typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) });
return Expression.Call(left, c, right);
case OperatorUsedWithString.Egal:
c = typeof(string).GetMethod("Equals", new Type[] { typeof(string) });
return Expression.Call(left, c, right);
}
}
if (p is OperatorUsedWithNumber)
{
switch ((OperatorUsedWithNumber)p)
{
case OperatorUsedWithNumber.Egal:
return Expression.Equal(left, right);
case OperatorUsedWithNumber.Inferieur:
return Expression.LessThan(left, right);
case OperatorUsedWithNumber.InferieurEgal:
return Expression.LessThanOrEqual(left, right);
case OperatorUsedWithNumber.Superieur:
return Expression.GreaterThan(left, right);
case OperatorUsedWithNumber.SuperieurEgal:
return Expression.GreaterThanOrEqual(left, right);
}
}
if (p is OperatorUsedWithDateTime)
{
switch ((OperatorUsedWithDateTime)p)
{
case OperatorUsedWithDateTime.PasPresent:
return Expression.Equal(left, Expression.Constant(null));
case OperatorUsedWithDateTime.Present:
return Expression.NotEqual(left, Expression.Constant(null));
}
}
throw new NotImplementedException();
}
}
和BuildLambda:
private static Expression BuildLambda(Expression parameter, Expression predicate)
{
var resultParameterVisitor = new ParameterVisitor();
resultParameterVisitor.Visit(parameter);
var resultParameter = resultParameterVisitor.Parameter;
return Expression.Lambda(predicate, (ParameterExpression)resultParameter);
}
我认为,我刚刚对此功能进行了更改,但我尝试了一些方法但没有工作。 所以欢迎一些帮助。
答案 3 :(得分:0)
我正在使用null
签入query
字符串
searchQ +=
$"({objPropertiesName[i]} != null && " +
$"{objPropertiesName[i]}.ToLower().Contains" +
$"(\"{searchTerm}\")) || ";
它的工作就像一种魅力。