如何在Dynamic LINQ中使用Contains时动态键入Cast到字符串?

我想使用动态LINQ查询来搜索类中所有属性中的一些文本。 我正在使用以下函数来创建表达式。 我正在将属性名称和搜索文本传递给方法。 在该方法中,如果属性类型是String,那么它工作正常。 如果属性类型是int,DateTime,GUID。 然后它不起作用。

我们知道Contains方法只用于元素数组或字符串。 我认为属性的值应该输入到字符串。 那怎么办呢? 带解释的解决方案是完整的。

我收集了这个代码。

public static Expression<Func> ContainsExp(string propertyName, string contains) { var parameterExp = Expression.Parameter(typeof(T), "type"); var propertyExp = Expression.Property(parameterExp, propertyName); MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); var someValue = Expression.Constant(contains, typeof(string)); var containsMethodExp = Expression.Call(propertyExp, method, someValue); return Expression.Lambda<Func>(containsMethodExp, parameterExp); } 

好吧,你可能知道在linq中使用ToString()是不可能的。

所以以下问题是:如何将其他类型转换为字符串。

对于数值 ,你有SqlFunctions.StringConvert ,但它只有double?重载double?decimal?

对于DateTime ,您可以在DateTime上应用SqlFunctions.StringConvert后使用SqlFunctions.StringConvert找到一些东西(这可能意味着至少3次调用SqlFunctions.DatePart ,年,月,日)

对于Guid ,我认为没有办法直接做到这一点。 一种方法(在db级别,如果你使用Sql Server)可能是一个Computed列。 计算列可以存储GUID的varchar转换表示。 也许有更好的方法。

无论如何,这里至少有一个样本应该适用于integerstring

  public static Expression> ContainsExp(string propertyName, string contains) { //first, get the type of your property var propertyType = typeof(T).GetProperty(propertyName).PropertyType; //no change var parameterExp = Expression.Parameter(typeof (T), "type"); Expression propertyExp = Expression.Property(parameterExp, propertyName); //if property's type is int if (propertyType == typeof (int)) { //convert your Expression to a nullable double (or nullable decimal), //so that you can use SqlFunctions.StringConvert propertyExp = Expression.Convert(propertyExp, typeof (double?)); //get the SqlFunctions.StringConvert method for nullable double var stringConvertMethod = typeof (SqlFunctions).GetMethod("StringConvert", new[] {typeof (double?)}); //call StringConvert on your converted expression propertyExp = Expression.Call(stringConvertMethod , propertyExp); } //no change var method = typeof (string).GetMethod("Contains", new[] {typeof (string)}); var someValue = Expression.Constant(contains, typeof (string)); var containsMethodExp = Expression.Call(propertyExp, method, someValue); return Expression.Lambda>(containsMethodExp, parameterExp); }