LINQ用户输入列WHERE子句

时间:2015-09-24 02:09:52

标签: c# mysql asp.net linq

有什么办法可以在查询中动态更改用户输入的WHERE子句吗?

用户将选择要过滤的列以及该列中要过滤的ID或内容。

这是我到目前为止的代码

 public List<AssetDetailsToDisplay> FilterGridview2(String Samplequery)
    {
        try
        {
            using (Data.AMSEntities model = new Data.AMSEntities())
            {
                var list = from asset in model.Assets
                           join employee in model.Employees on asset.owner_id equals employee.employee_id into assetlist
                           where(Samplequery) // this is where the user inputed query should be executed

                           select new AssetDetailsToDisplay
                           {
                               id = asset.AssetSubClassRel.id,
                               asset_id = asset.asset_id,
                               short_description = asset.short_description,
                               inventory_id = asset.inventory_id,
                               class_id = asset.AssetClassRel.table_value,
                               subclass_id = asset.AssetSubClassRel.table_value,
                               ast_status_id = asset.AssetStatusRel.table_value,
                               location_id = asset.AssetLocationRel.table_value,
                               subclass_key = asset.AssetSubClassRel.table_key

                           };
                return list.ToList();
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

用户将要输入的查询示例

 <asp:TextBox ID="txtSample" CssClass="form-control" Style="width: 120px;" runat="server" Text="owner_id <> ''"/>
代码背后的代码:

protected void Page_Load(object sender, EventArgs e)
    {
     Business.Users users = new Business.Users();
     string samplequery = txtSample.Text
     users.FilterGridview2(samplequery);
    }

4 个答案:

答案 0 :(得分:0)

是的,你可以这样做:

public class MyFilter 
{
   public int? ById { get; set; }
   public string ByName { get; set; }
   /// etc...
}

IQuerayble<Asset> GetAssets(MyFilter filter) 
{
    IQueryable<Asset> query = model.Assets; 
    if (filter.ById.HasValue)
        query = query.Where(a => a.Id == filter.ById.Value);
    if (!string.IsNullOrWhitespace(filter.ByName))
        query = query.Where(a => a.Id == filter.ByName);

    query = query.Select(... // your select code here);
    return query;
}

如果您只想传递列名和值,那么您必须查看反射和C#Expression构建器。

答案 1 :(得分:0)

您是否尝试在任何领域进行搜索?

也许你应该试试这个IQueryable扩展。它可以搜索任何字符串属性

public static IQueryable<T> Relevant<T>(this IQueryable<T> qry, string keyword, bool AllKeywordMustExist = true, char keywordSeparator = ' ')
    {
        var parameter = Expression.Parameter(typeof(T), "relev");

        var objectType = typeof(T);
        var stringProperties = objectType.GetProperties().Where(m => m.PropertyType == typeof(string));

        var keywords = keyword.Split(keywordSeparator)
            .Where(m => !string.IsNullOrEmpty(m))
            .Select(m => m.ToLower())
            .Distinct();

        Expression completeExpression = Expression.Constant(AllKeywordMustExist);
        foreach (var keywordExpression in keywords.Select(m => Expression.Constant(m)))
        {
            Expression keywordCompleteExpression = Expression.Constant(false);
            foreach (var prop in stringProperties)
            {
                var containExpression = CreatePropertyContainExpression(parameter, prop, keywordExpression);
                var notNullExpression = Expression.NotEqual(Expression.PropertyOrField(parameter, prop.Name), Expression.Constant(null));
                var notNullContaintExpression = Expression.Condition(notNullExpression, containExpression, Expression.Constant(false));

                keywordCompleteExpression = Expression.Or(keywordCompleteExpression, notNullContaintExpression);
            }

            if (AllKeywordMustExist)
            {
                completeExpression = Expression.And(completeExpression, keywordCompleteExpression);
            }
            else
            {
                completeExpression = Expression.Or(completeExpression, keywordCompleteExpression);
            }
        }

        return qry.Where(Expression.Lambda<Func<T, bool>>(completeExpression, parameter));
    }

 private static Expression CreatePropertyContainExpression(Expression instance, PropertyInfo instanceProperty, Expression keyword)
    {
        var containMethod = typeof(string).GetMethods().FirstOrDefault(m => m.Name == "Contains" && m.GetParameters().Length == 1);
        var toLowerMethod = typeof(string).GetMethods().FirstOrDefault(m => m.Name == "ToLower" && m.GetParameters().Length == 0);

        var propParam = Expression.PropertyOrField(instance, instanceProperty.Name);
        var tolowerExp = Expression.Call(propParam, toLowerMethod);
        var containExpression = Expression.Call(tolowerExp, containMethod, keyword);

        return containExpression;
    }

要使用它,只需致电

data.Relevant("rob");

这是一个小提琴https://dotnetfiddle.net/4iXf9M

答案 2 :(得分:0)

我认为这可能会对你有所帮助。看看这个article

无论如何,我自己从来没有尝试过。

答案 3 :(得分:-1)

这样的东西?:

 var list = from asset in model.Assets
                       join employee in model.Employees on asset.owner_id equals employee.employee_id into assetlist
                       where asset.subclass_id == subclass_id