ASP.NET搜索表单 - 动态Linq到SQL?

tom*_*m d 5 linq asp.net linq-to-sql

我有一个搜索表单,允许用户以几种不同的方式搜索几个不同的字段.这是我的代码示例.

var claims = from c in db.Claims select c;

switch (ddlSearchField.Text)
{
    case "StartsWith":
        claims = claims.Where(c => c.companyFileID.StartsWith(txtSearchBox.Text));
        break;

    case "Equals":
        claims = claims.Where(c => c.companyFileID == txtSearchBox.Text);
        break;

    case "Contains":
        claims = claims.Where(c => c.companyFileID.Contains(txtSearchBox.Text));
        break;
}
Run Code Online (Sandbox Code Playgroud)

我有大约十个不同的字段,用户可以搜索,所以我的外部开关语句非常大.必须有一种更优雅的方式来实现这一目标.

Tho*_*que 3

您可以通过创建扩展方法来重构代码的某些部分。像这样的东西:

static class QueryableExtensions
{
    private static MethodInfo StringContainsMethod;
    private static MethodInfo StringStartsWithMethod;

    static QueryableExtensions()
    {
        Type[] singleStringParam = new[] {typeof(string)};
        StringContainsMethod = typeof(string).GetMethod("Contains", singleStringParam);
        StringStartsWithMethod = typeof(string).GetMethod("StartsWith", singleStringParam);
    }

    public static IQueryable<T> AppendTextFilter<T>(this IQueryable<T> queryable, Expression<Func<T, string>> memberSelector, string condition, string value)
    {
        Expression expression = null;
        switch (condition)
        {
            case "StartsWith":
                expression = Expression.Call(
                                memberSelector.Body,
                                StringStartsWithMethod,
                                Expression.Constant(value));
                break;

            case "Equals":
                expression = Expression.Equal(
                                memberSelector.Body,
                                Expression.Constant(value));
                break;

            case "Contains":
                expression = Expression.Call(
                                memberSelector.Body,
                                StringContainsMethod,
                                Expression.Constant(value));
                break;

            default:
                throw new NotSupportedException(string.Format("'{0}' is not a supported condition", condition));
        }

        var lambda = Expression.Lambda<Func<T, bool>>(
                        expression,
                        memberSelector.Parameters);
        return queryable.Where(lambda);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样使用它:

var claims = db.Claims
             .AppendTextFilter(c => c.companyFileID, ddlSearchField.Text, txtSearchBox.Text)
             .AppendTextFilter(c => c.someOtherProperty, ddlOtherSearchField.Text, txtOtherSearchBox.Text)
             ...;
Run Code Online (Sandbox Code Playgroud)