簡體   English   中英

Linq動態構建查詢,無具體類型

[英]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.

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