我有一个方法 BuildQuery
动态生成查询。它适用于 SQL:
static MyType[] GetDataFromDB(MyDataContext db, string city, string district, string region, string country, string zip)
{
var q = BuildQuery(db.MyTable.AsQueryable(), city, district, region, country, zip);
return q.ToArray();
}
private static IQueryable<MyType> BuildQuery(IQueryable<MyType> q, string city, string district, string region, string country, string zip)
{
if (!string.IsNullOrEmpty(city))
q = q.Where(p => p.City.Contains(city));
if (!string.IsNullOrEmpty(district))
q = q.Where(p => p.District.Contains(district));
if (!string.IsNullOrEmpty(zip))
q = q.Where(p => p.Zip == zip);
if (!string.IsNullOrEmpty(region))
q = q.Where(p => p.Region.Contains(region));
if (!string.IsNullOrEmpty(country))
q = q.Where(p => p.Country == country);
return q;
}
(实际上,这个查询有点复杂。)这很适合用一些 LIKE
构建 SQL 查询。 .
现在我想对 MyType
的数组使用相同的查询:
MyType[] SelectFromResult(MyType[] loc, string city, string district, string region, string country, string zip)
{
var q = BuildQuery(loc, city, district, region, country, zip);
return q.ToArray();
}
当然这不能编译因为MyType[]
是一个 IEnumerable<MyType>
,不是 IQueryable<MyType>
.更改 BuildQuery
中第一个参数的类型至 IEnumerable<MyType>
,编译并适用于数组,但不会构建 SQL 查询。
我想我可以让 BuildQuery 成为一个通用方法,但是怎么做呢?有什么想法吗?
最佳答案
LINQ 的优点之一是您可以将函数彼此连接(链接)在一起。这是可能的,因为引入了扩展方法。
如果稍微更改 BuildQuery 函数,则可以将其用作任何 LINQ 函数。参见 extension methods demystified
private static IQueryable<MyType> BuildQuery(this IQueryable<MyType> q,
string city, string district, string region, string country, string zip)
{
...
注意 IQueryable
之前的这个词.这允许您在方法调用之前放置方法的第一个参数(IQueryable)。
回到你的问题
任何IEnumerable<TSource>
可以转换为 IQueryable<TSource>
使用 AsQueryable()
,所以也是一个TSource[]
MyType[] loc = ...
IQueryable<MyType> myQueryable = loc.AsQueryable()
.BuildQuery(city, district, ....);
也许你应该给它一个合适的名字:ToQuery`` 怎么样?
要执行查询,请用它做您想做的事:ToList
/ToArray
/计数/FirstOrDefault/...
顺便说一句,当创建类似 LINQ 的函数时,通常最好返回 IEnumerable/IQueryable 而不是 List/Array 等,除非你真的知道你的调用者想要完整的序列。如果你调用ToList()
就太浪费了而你的来电者只想要 FirstOrDefault()
关于sql - 如何编写一个方法来为 SQL 和数组构建查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56020737/