簡體   English   中英

使用 Linq 動態查詢數據集

[英]Dynamically Query a data set using Linq

我有一個要動態查詢的數據集。 如果我明確定義字段名稱,則此代碼可以正常工作,但我不想這樣做。 我想使用字段名稱的變量動態查詢數據。 我應該如何接近這個?

這有效:

var dataField = "DemandStatusName";
var searchParam = form.GetValues("columns[" + j + "][search][value]").FirstOrDefault();

if(searchParam != "")
{
    dataSet = (from a in dataSet
               where a.DemandStatusName.Contains(searchParam)
               select a);
}

但這不會:

var dataField = "DemandStatusName";
var searchParam = form.GetValues("columns[" + j + "][search][value]").FirstOrDefault();

if(searchParam != "")
{
    dataSet = (from a in dataSet
               where dataField.Contains(searchParam)
               select a);
}

我應該如何接近這個?

LINQ 的主要好處之一是您可以獲得類型安全。 通過動態查詢,您本質上失去了這種好處。 雖然不是真正的“動態”,但您可以通過編寫包含要查詢的特定字段的擴展方法來保持這種優勢:

public static IQueryable<MyTable> WhereContains(this IQueryable<MyTable> source, string field, string value)
{
  switch (field)
  {
    case nameof(MyTable.SomeField):
      return source.Where(a => a.SomeField.Contains(value));
    case nameof(MyTable.SomeOtherField):
      return source.Where(a => a.SomeOtherField.Contains(value));
    // ... etc
    default:
      throw new ArgumentOutOfRangeException($"Unexpected field {field}");
  }
}

這樣,您的代碼可以調用以下內容:

var dataField = "DemandStatusName";
var searchParam = form.GetValues("columns[" + j + "][search][value]").FirstOrDefault();

dataset.WhereContains(dataField, searchParam).OrderBy(a => a.Whatever)

話雖如此,要真正回答您的問題,您在技術上可以動態構建 LINQ 表達式。 這可能看起來像這樣,但要注意性能會很差,意外的值可能會破壞它和/或打開一些安全漏洞,特別是如果它們來自用戶輸入:

var table = Expression.Parameter(typeof(MyTable));
var property = Expression.PropertyOrField(table, dataField);
var param = Expression.Constant(searchParam);
var contains = Expression.Call(property, "Contains", Type.EmptyTypes, searchParam);
var expression = Expression.Lambda<Func<MyTable,bool>>(contains, table);

var result = dataset.Where(expression);

有必要使用LINQ嗎? 動態 SQL(帶參數)會容易得多。

var dataField = "DemandStatusName";
var searchParam = form.GetValues("columns[" + j + "][search][value]").FirstOrDefault();
var sql = string.Format("select * from tableName where {0} = @param", dataField);

if(searchParam != "")
{
    dataSet = context.Database.SqlQuery<YourEntity>(sql,
                  new SqlParameter("param", searchParam));
}

暫無
暫無

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

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