我有两个DbSets,Foo和Bar. Foo有一个标识字符串属性FooName,而Bar有一个标识字符串属性BarName.
我正在设计一个非常简单的搜索功能,其中用户的查询字词可以等于或包含在识别名称中.
public ActionView SearchFoo(string query) { var equalsQuery = db.Foo.Where(f => f.FooName.Equals(query)); var containsQuery = db.Foo.Where(f => f.FooName.Contains(query)).Take(10); // Don't want too many or else a search for "a" would yield too many results var result = equalsQuery.Union(containsQuery).ToList(); ... // go on to return a view } public ActionView SearchBar(string query) { var equalsQuery = db.Bar.Where(f => f.BarName.Equals(query)); var containsQuery = db.Bar.Where(f => f.BarName.Contains(query)).Take(10); // Don't want too many or else a search for "a" would yield too many results var result = equalsQuery.Union(containsQuery).ToList(); ... // go on to return a view }
显然我想要一些辅助方法,如下所示:
public IList<T> Search<T>(string query,DbSet<T> set) { var equalsQuery = set.Where(f => ???.Equals(query)); var containsQuery = set.Where(f => ???.Contains(query)).Take(10); // Don't want too many or else a search for "a" would yield too many results var result = equalsQuery.Union(containsQuery).ToList(); ... // go on to return a view }
我最初尝试添加一个Func< T,string>到搜索参数,我可以使用f => f.FooName和b => b.BarName,但LINQ to Entities在执行查询期间不支持lambda表达式.
我一直在摸索如何提取这种重复.
解决方法
您可以使用Expression< Funt< T,string>>实现此目的.
public IList<T> Search<T>(string query,DbSet<T> set,Expression<Func<T,string>> propExp) { MethodInfo method = typeof(string).getmethod("Contains",new[] { typeof(string) }); ConstantExpression someValue = Expression.Constant(query,typeof(string)); MethodCallExpression containsMethodExp = Expression.Call(propExp.Body,method,someValue); var e = (Expression<Func<T,bool>>) Expression.Lambda(containsMethodExp,propExp.Parameters.ToArray()); var containsQuery = set.Where(e).Take(10); BinaryExpression equalExpression = Expression.Equal(propExp.Body,someValue); e = (Expression<Func<T,bool>>) Expression.Lambda(equalExpression,propExp.Parameters.ToArray()); var equalsQuery = set.Where(e); var result = equalsQuery.Union(containsQuery).ToList(); }
那你就叫它:
Search ("myValue",fooSet,foo=>foo.FooName);
public static IList<T> Search<T>(this DbSet<T> set,string query,string>> propExp)
并称之为:
FooSet.Search ("myValue",foo=>foo.FooName);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。