簡體   English   中英

我可以在LINQ Where子句中使用屬性嗎?

[英]Can I Use a Property in a LINQ Where Clause?

首先,如果這個標題是垃圾桶,我深表歉意。 我是C#和ASP的新手,我什至不知道如何問這個問題。

我正在嘗試將搜索功能合並到我的網頁中。 我有一個文本框,其中包含用戶想要的搜索詞。 下拉列表將選擇要在數據庫表中搜索的字段。因此,如果有姓和名,用戶可以選擇要搜索的名字。我有一個名為SearchField {get;的屬性。 set;},它將保留用戶在下拉菜單中選擇的值,但是當我嘗試在LINQ語句中將其與Contains(blah)一起使用時,出現錯誤。

由於我對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();
    }

錯誤:對象不包含“包含”的定義,並且最著名的擴展方法重載Queryable.Contains .....需要類型為IQueryable的接收器

您可以在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));

您需要動態創建表達式樹,該樹將過濾表並僅返回匹配的值。

這是字符串屬性所需要的(故意分布在多行上):

// 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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM