C#Dynamic Linq:在Where子句中实现“赞”

时间:2019-04-08 04:53:34

标签: c# sql-server linq dynamic dynamic-linq

因此,我想对我的数据进行常规分类。我有这段代码从数据库中获取数据,该数据库将仅提取包含value的数据。

using System.Linq.Dynamic;

public static IQueryable<object> SortList(string searchString, Type modelType, 
    IQueryable<object> model)
{
    ....

    string toStringPredicate = type == typeof(string) ? propertyName + 
        ".Contains(@0)" : propertyName + ".ToString().Contains(@0)";
    model = model.Where(propertyName + " != NULL AND " + toStringPredicate, value);
}

模型是这样的:

public class ManageSubscriberItems
{
    public int? UserId { get; set; }
    public string Email { get; set; }
    public Guid SubscriberId { get; set; }
}

当我打电话时:

models = (IQueryable<ManageSubscriberItems>)EcommerceCMS.Helpers.FilterHelper
    .SortList(searchString, typeof(ManageSubscriberItems), models);

if(models.Any())

它抛出此错误:

  

“ LINQ to Entities无法识别方法'System.String   ToString()'方法,并且该方法无法转换为商店   表达。”


编辑

我找到了问题,但仍然无法解决。因此,如果属性不是string,则在调用.ToString().Contains()时将引发错误。

model = model.Where(propertyName + " != NULL AND " + propertyName + 
    ".ToString().Contains(@0)", value);

我想要在查询中实现LIKE。谁能帮我吗?

4 个答案:

答案 0 :(得分:6)

如果您将System.Linq.Dynamic.Core EF Core 一起使用,则可以选择使用

var q = context.Cars.Where(config, "DynamicFunctions.Like(Brand, \"%a%\")");

有关示例,请参见此链接: https://github.com/StefH/System.Linq.Dynamic.Core/blob/6fc7fcc43b248940560a0728c4d181e191f9eec1/src-console/ConsoleAppEF2.1.1/Program.cs#L117

我刚刚在linqpad中测试了连接到真实数据库的过程,并且这样的代码行得通吗?

var result1 = Entity1s.Where("Url != NULL AND it.Url.Contains(@0)", "e");


[UPDATE 2019-04-17]]

如果您不知道类型,可以将其强制转换为 object ,然后将其强制转换为 string

代码:

var r = Entity1s.Select("string(object(Rating))").Where("Contains(@0)", "6");

答案 1 :(得分:4)

所以这里的问题是 IQueryable 发生在 SQL 服务器上,而不是C#中,所以 SQL 服务器不知道关于 .toString()方法的任何事情。 因此=>和 Like运算符可以在字符串上自动运行..因此,它是SQL Server中的nvarchar和varchar数据类型。 如果您可以告诉我更多有关您的问题以及您想要实现的目标的信息,我可以给您一个如何实现它的示例。 可以做一个样本。

答案 2 :(得分:0)

您已经在Linq中有了一个“赞”,它可以在数据库中运行并可以使用字符串,它称为“ IndexOf”:

 ((IQueryable)model).Where(m => m.Property.IndexOf(searchString) == 1);

根据MSDN: IndexOf(string)

'如果找到该字符串,则从零开始的索引位置,否则为-1。如果value为Empty,则返回值为0。'

答案 3 :(得分:0)

  

因此,我想对我的数据进行常规分类。

不是固定'invoke issue',而是一般方法应使用泛型,例如

public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, 
                                       string property,
                                       bool asc = true) where T : class
{
    //STEP 1: Validate MORE!
    var searchProperty = typeof(T).GetProperty(property);
    if (searchProperty == null) throw new ArgumentException("property");

     ....

    //STEP 2: Create the OrderBy property selector
    var parameter = Expression.Parameter(typeof(T), "o");
    var selectorExpr = Expression.Lambda(Expression.Property(parameter, property), parameter)        

    //STEP 3: Update the IQueryable expression to include OrderBy
    Expression queryExpr = source.Expression;
    queryExpr = Expression.Call(typeof(Queryable), asc ? "OrderBy" : "OrderByDescending",
                                  new Type[] { source.ElementType, searchProperty.PropertyType },
                                 queryExpr, 
                                selectorExpr);

    return source.Provider.CreateQuery<T>(queryExpr);
}

具有属性名称字符串和方向,通常用于对数据进行“列排序”。

接下来是关系谓词的到来,从头开始做时'Linq.Dynamic'似乎很合理,但是有通用的规范形式exists