Могу ли я использовать свойство в пункте LINQ Where? - PullRequest
0 голосов
/ 19 апреля 2019

Прежде всего, я прошу прощения, если заголовок этого мусора.Я новичок в C # и ASP и даже не знаю, как задать этот вопрос.

Я пытаюсь включить функцию поиска в мою веб-страницу.У меня есть текстовое поле, которое будет принимать запрос, который хочет пользователь.В раскрывающемся списке будет указано ПОЛЕ моей таблицы базы данных, в которой будет выполняться поиск. Поэтому, если есть фамилии и имена, пользователь может выбрать, в каком из них выполнять поиск. У меня есть свойство SearchField {get;set;}, который будет содержать значение, выбранное пользователем в раскрывающемся списке, но когда я пытаюсь использовать его в своем операторе LINQ вместе с Contains (бла), я получаю ошибку.

Я очень мало пробовал, так как я действительно мало знаю о C # или о том, что ошибка говорит мне.

cshtml-файл

<form>
    <p>
        <select asp-for="SearchField" class="form-control">
            <option value="FirstName">First Name</option>
            <option value="LastName">Last Name</option>
            <option value="Salary">Salary</option>
            <option value="Gender">Gender</option>
            <option value="Department">Department</option>
            <option value="Location">Location</option>
            <option value="Performance">Performance</option>
        </select>
        Search: <input type="text" asp-for="SearchString" class="form-control" />
        <input type="submit" value="Filter" class="form-control" />
    </p>
</form>

cs-файл

   [BindProperty(SupportsGet = true)]
   public string SearchField { get; set; }

   public async Task OnGetAsync()
    {
        var employees = from x in _context.Employee
                     select x;
        if (!string.IsNullOrEmpty(SearchString))
        {
            employees = employees.Where(x => x.SearchField.Contains(SearchString));
        }
        Employee = await employees.ToListAsync();
    }

Ошибка: объект не содержит определения для «Contains» и наиболее известной перегрузки метода расширения Queryable.Contains..... требуется приемник типа IQueryable

Ответы [ 2 ]

1 голос
/ 19 апреля 2019

Вы можете использовать отражение в C #, чтобы получить свойство на основе вашего SearchField и сравнить значение свойства с вашей SearchString. https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection

В вашем случае:

public async Task OnGetAsync()
    {
        var employees = from x in _context.Employee
                     select x;
        if (!string.IsNullOrEmpty(SearchString))
        {
            employees = employees.Where(x => x.GetType().GetProperty(SearchField).GetValue(x, null).ToString() == SearchString);
        }
        Employee = await employees.ToListAsync();
    }

Вы также можете использовать String.Contains следующим образом:

employees = employees.Where(x => x.GetType().GetProperty(SearchField).GetValue(x, null).ToString().Contains(SearchString, StringComparison.InvariantCultureIgnoreCase));
0 голосов
/ 19 апреля 2019

Вам необходимо динамически создать дерево выражений, которое будет фильтровать вашу таблицу и возвращать только совпадающие значения.

Вот то, что вам нужно для строковых свойств (оно намеренно распределено по многим строкам):

// Expression to construct: (Employee parameter) => parameter.GetPropertyValue(searchField).Contains(SearchValue)
var parameter = Expression.Parameter(typeof(Employee));
var employeePropertyValue = Expression.Property(parameter, searchField);

var constainsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var contains = Expression.Call(employeePropertyValue, containsMethod, Expression.Constant(searchString));
var whereCondition = (Expression<Func<Employee, bool>>)Expression.Lambda(contains, parameter);

// filtering
employees = employees.Where(whereCondition);

Для нестроковых свойств вам нужно будет создать другое условие в зависимости от типа свойства (например, свойство Enum будет храниться в базе данных в целочисленном виде, поэтому вам нужно преобразовать SearchValue в Gender и использовать Expression.Equal)

...