sql - 如何编写一个方法来为 SQL 和数组构建查询?

标签 sql linq object

我有一个方法 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/

相关文章:

javascript - 在javascript中,NEW函数是否有可能返回NULL?

java - 将对象克隆到数组列表中,java

c# - 使用列默认值更新表列

java - SQL 异常 com.microsoft.sqlserver.jdbc.sqlserverexception : login failed for user '' . Clientconnectionid:073b35b2-0e56-460d-8353-9de2b2d0ecff

SQL 通过/左连接按组获取最大 n 的所有行

linq - NHibernate linq 提供者 datediff

sql - 组合两个 SQL SELECT COUNT(*) 语句

sql - SSIS错误: Invalid object name - but object exists and query runs in SSMS

c# - 如何使用 LINQ 获取 id 的列表作为 int

javascript - Javascript 对象属性的奇怪相等问题