我正在编写一个我认为应该是相对简单的Windows表单应用程序。我正在使用LINQ to SQL,尽管我以前从未使用过它。我们有一个SQL Server数据库,我正在创建一个访问该数据库的前端。我正在尝试找出使用它搜索多个(任意数量)搜索参数的最有效方法。
在windows表单中,我创建了一个包含每个搜索键及其要搜索的值的字典,并将其传递给我的search()方法。我正在尝试找到一种方法来搜索数据库中的每个键及其关联值。这就是我想要做的:
public IQueryable<Product> Search(Dictionary<string, string> searchParams)
{
DBDataContext dc = new DBDataContext();
var query = dc.Products;
foreach (KeyValuePair<string, string> temp in searchParams)
{
query = query.Where(x => x.(temp.Key) == temp.Value);
}
return query;
}我意识到x.(temp.Key)在语法上是不正确的,但我希望这说明了我正在尝试做的事情。我想知道是否有其他方法可以在不执行巨大的switch语句(或者if/else if tree)的情况下完成我想要做的事情。
编辑
所以,我对它做了一点修改,但我仍然有问题。这是我目前所拥有的:
public IQueryable<Product> Search(Dictionary<string, string> searchParams)
{
DBDataContext dc = new DBDataContext();
string sQuery = "";
foreach (KeyValuePair<string, string> temp in searchParams)
{
sQuery += temp.Key + "=" + temp.Value + " AND ";
}
var query = dc.Products.Where(sQuery);
return query;
}根据LINQ动态查询库的文章,这应该没问题。下面是我得到的错误:
无法从用法中推断出方法'System.Linq.Queryable.Where(System.Linq.IQueryable,System.Linq.Expressions.Expression>)‘的类型参数。尝试显式指定类型参数。
发布于 2010-10-29 14:35:23
这里有一个使用Dynamic LINQ Query Library的示例(我刚刚对它进行了测试)。
using System.Linq.Dynamic;
// ...
Dictionary<string, string> searchParams = new Dictionary<string,string>();
searchParams.Add("EmployeeID", "78");
searchParams.Add("EmpType", "\"my emp type\"");
IQueryable<Employee> query = context.Employees;
foreach (KeyValuePair<string, string> keyValuePair in searchParams)
{
query = query.Where(string.Format("{0} = {1}", keyValuePair.Key, keyValuePair.Value));
}
List<Employee> employees = query.ToList();并且,为了让绝对清楚,这段代码实际上是有效的,这里是实际生成的:
FROM [HumanResources].[Employee] AS [t0]
WHERE ([t0].[EmpType] = @p0) AND ([t0].[EmployeeID] = @p1)',N'@p0 nvarchar(11),@p1 int',@p0=N'my emp type',@p1=78发布于 2010-10-29 02:40:58
如果由于某种原因不需要字典,我会让你的搜索方法如下:
public IQueryable<Product> Search( Func<Product, bool> isMatch )
{
DBDataContext dc = new DBDataContext();
return dc.Products.Where( isMatch ).AsQueryable();
}然后,您可以像这样使用方法:
Obj.Search( item => item.Property1 == "Hello" && item.Property2 == "World" );有什么原因让你不能这么做吗?
编辑:添加了AsQueryable()
编辑:用于使用字符串的动态查询
请看这里,看看这是否有帮助。我还没有用过它,但看起来就是你要找的:http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
就我个人而言,我通常更喜欢类型安全的Expression>方法,因为如果需要字符串,这将为您提供编译时errors...but,那么看起来是最好的方法。
基于上面的链接,看起来你应该能够做到:
query = query.Where( String.Format("{0}={1}",dict.Key,dict.Value) );编辑:字符串构建示例
因此,其中一个问题是,您的sql查询将以字符串末尾的AND结束,但在it...so之后没有条件,可能尝试更改为this...syntax可能会稍微关闭,但应该是正确的:
public IQueryable<Product> Search(Dictionary<string, string> searchParams)
{
DBDataContext dc = new DBDataContext();
StringBuilder sQuery = new StringBuilder();
foreach (KeyValuePair<string, string> temp in searchParams)
{
if( sQuery.Length > 0 ) sQuery.Append(" AND ");
sQuery.AppendFormat("{0}={1}",temp.Key,temp.Value);
}
var query = dc.Products.Where(sQuery.ToString());
return query;
}这将只在第一个条件之后的条件上使用"AND“。希望这能帮上忙。
这是离题的,但“为什么”我使用StringBuilder的字符串连接方式会导致字符串被销毁,并在内存中创建一个新的字符串4次,每个loop...so更改为一个StringBuilder,因为这将创建一个缓冲区,可以填充,只有在必要时调整大小。
发布于 2010-10-29 02:49:49
您可以使用以下方法,而不是使用字典:
using System.Linq.Expressions;
// ...
public static IQueryable<Product> Search(Expression<Func<Product, bool>> search)
{
DBDataContext dc = new DBDataContext();
return dc.Products.Where(search);
}你可以这样使用它:
Search(p => p.Name == "Name" && p.Id == 0);您也不会局限于字符串属性。
https://stackoverflow.com/questions/4046009
复制相似问题