[英]Linq build query dynamically with no concrete Type
實際上,我正在部署通用搜索控件,這是因為我有許多需要“搜索”的實體
我的方法是:容易擺弄
public interface ISearchable
{
object SearchType { get; }
string SearchField { get; set; }
string SearchField2 { get; set; }
string DisplayField { get; set; }
decimal SelectedKey { get; set; }
}
類別必須實現此插入操作,如下所示:
public partial class PeopleInfoBasica : ISearchable
{
public string SearchField
{
get { return StrSearchKey; }
}
public string SearchField2
{
get { return StrSearchKeyPhoneDir; }
}
public string DisplayField
{
get { return StrNombreUsuario; }
}
public decimal SelectedKey
{
get { return NumIdContrato; }
}
public object SearchType
{
get { return new PeopleInfoBasica(); }
}
}
還有許多其他方法可以實現它。現在我的通用對象必須對過濾器進行如下處理:
private Task PrimerFiltro(string primerfiltro)
{
MiContext db = Credentials.Db;
// Se aplica el primer filtro a la lista
var itemsQ = (from i in db.**Here I Need to Specify dynamically the type**
where i.SearchField.Contains(primerfiltro)
select i
).OrderBy(x => x.DisplayField);
filteredList = itemsQ.ToList();
ListaBase = filteredList;
}
我的問題是:有一種方法可以動態地將類型指定為linq? 也許另一個方法?
var itemsQ = (from i in db.
這里我需要動態指定 where i.SearchField.Contains(primerfiltro) select i ).OrderBy(x => x.DisplayField);
的類型 where i.SearchField.Contains(primerfiltro) select i ).OrderBy(x => x.DisplayField);
使您的方法通用,以接受實現ISearchable
接口的類型參數T
,並添加類型Expression<Func<T,bool>>
的參數,該參數可由Queryable.Where()
方法使用:
private Task PrimerFiltro<T>(string primerfiltro, Expression<Func<T,bool>> filterExpression) where T: ISearchable
{
var db = Credentials.Db;
var set = db.CreateObjectSet<T>();
var filteredList = set.Where(filterExpression)
.OrderBy(x => x.DisplayField)
.ToList();
ListaBase = filteredList;
}
請注意,我正在使用CreateObjectSet()
方法動態獲取與類型T
相對應的實體集。
此解決方案使用SQL查詢數據庫。 我已經放下了刪除界面以縮短答案的自由。
一,模型類:
[SearchField("StrSearchKey")]
public partial class PeopleInfoBasica
{
public string StrSearchKey { get; set; } //The property to search on. Created by EF or code-first
...
}
注意帶有搜索字段的新屬性:
public class SearchFieldAttribute : Attribute
{
public SearchFieldAttribute(string searchField)
{
SearchField = searchField;
}
public string SearchField { get; private set; }
}
要獲取searchField,請使用:
var attribute = type.GetCustomAttributes(typeof(SearchFieldAttribute), false).FirstOrDefault() as SearchFieldAttribute;
var searchField = attribute.SearchField;
請在使用上述內容之前添加安全檢查。
結合以上內容,您現在應該可以使用以下查詢:
_db.Set(yourType).SqlQuery(String.Format("SELECT * FROM dbo.{0} WHERE {1} LIKE '%{2}%'", tableName, searchField, primerfiltro))
表名稱可以從類名稱或EF中找到。 取決於您是否使用CodeFirst,是否具有復數形式等。
請注意,我首先嘗試了一種構建表達式樹的解決方案,但是存在無法使用OfType()的問題。
我仍然認為最好的解決方案是嘗試使搜索通用的方法,或者簡單地為每個類編寫查詢。 它可能是更多的代碼,但是不容易被破壞。
上面的代碼容易受到SQL注入的影響,因此請當心。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.