我想使用linq to sql构建通用搜索窗口。
这就是我想要做的事情:
class SearchWindow<T> : Form : Where T: class
{
public SearchWindow(Func<T, string> codeSelector,
Func<T, string> nameSelector)
{
var db = new DataContext();
var table = db.GetTable<T>();
var query = from item in table where
codeSelector(item).Contains(someText) &&
nameSelector(item).Contains(someOtherText)
select item;
}
}
我试图像使用它一样:
var searchWindow = new SearchWindow<SomeTable>(x => x.CodeColumn,
y => y.NameColumn).Show();
Bud悲伤地说,这不起作用,我读到了表达树,所以我试着和他们一起做,我得到了:
public SearchWindow(codeColumn, nameColumn)
{
Table<T> table = db.GetTable<T>();
var instanceParameter = Expression.Parameter(typeof(T), "instance");
var methodInfo = typeof(string).GetMethod("Contains",
new Type[] { typeof(string) });
var codigoExpression = Expression.Call(Expression.Property(instanceParameter,
codeColumn),
methodInfo,
Expression.Constant("someText",
typeof(string)));
var nombreExpression = Expression.Call(Expression.Property(instanceParameter,
nameColumn),
methodInfo,
Expression.Constant("someOtherText",
typeof(string)));
var predicate = Expression.Lambda<Func<T, bool>>(
Expression.And(codigoExpression, nombreExpression), instanceParameter);
var query = table.Where(predicate);
}
要使用它,我需要做:
new SearchWindow<SomeTable>("codeColumn", "nameColumn");
但是我不喜欢需要将列名作为字符串输入的方法,有没有办法以类似于我的第一种方式(为了进行智能感知和强类型)的方式来做?
感谢您的帮助。
答案 0 :(得分:2)
未经测试,但类似:
static IQueryable<T> Search<T>(
IQueryable<T> source,
Expression<Func<T, string>> codeSelector,
Expression<Func<T, string>> nameSelector,
string code, string name)
{
var row = Expression.Parameter(typeof(T), "row");
var body = Expression.AndAlso(
Expression.Call(
Expression.Invoke(codeSelector, row),
"Contains", null,
Expression.Constant(code, typeof(string))),
Expression.Call(
Expression.Invoke(nameSelector, row),
"Contains", null,
Expression.Constant(name, typeof(string))));
var lambda = Expression.Lambda<Func<T, bool>>(body, row);
return source.Where(lambda);
}
您将表格(GetTable<T>
)作为source
传递,并使用lambdas表示列(x => x.CodeColumn
/ y => y.NameColumn
等)。
更新;在LINQ-to-Objects上进行测试,我希望它也适用于LINQ-to-SQL:
var data = new[] {
new { Code = "abc", Name = "def"},
new { Code = "bcd", Name = "efg"},
new { Code = "ghi", Name = "jkl"}
}.AsQueryable();
var filtered = Search(data, x => x.Code, x => x.Name, "b", "f");
var arr = filtered.ToArray();
答案 1 :(得分:0)
使用PredicateBuilder - 它会为你做繁重的工作。