实际上我正在部署通用搜索控件,这是因为我有许多实体需要"搜索"
我的aproach: interfase ISearshable
public interface ISearchable
{
object SearchType { get; }
string SearchField { get; set; }
string SearchField2 { get; set; }
string DisplayField { get; set; }
decimal SelectedKey { get; set; }
}
clases必须实现这样的interfase:
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);
答案 0 :(得分:2)
使您的方法通用接受实现T
接口的类型参数ISearchable
,并添加可由Queryable.Where()
方法使用的Expression<Func<T,bool>>
类型的参数:
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
类型对应的实体集。
答案 1 :(得分:2)
此解决方案使用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注入攻击,所以请注意。