首页 / 知识

在C#/。NET3.5中构造动态SQL查询的最佳方法?

2023-04-15 08:48:00

在C#/。NET3.5中构造动态SQL查询的最佳方法?

Best way of constructing dynamic sql queries in C#/.NET3.5?

我目前正在处理的一个项目涉及重构C#Com对象,该对象用作对某些Sql 2005数据库的数据库访问层。

现有代码的作者已使用字符串和许多if语句手动构建了所有sql查询,以构造相当复杂的sql语句(?10个联接,> 10个子选择,?15-25个条件和GroupBy的条件) 。基本表始终是相同的,但是联接,条件和分组的结构取决于传递到我的类/方法中的一组参数。

像这样构造sql查询确实可以,但是它显然不是一个非常优雅的解决方案(并且同样很难阅读/理解和维护)...我自己可以编写一个简单的" querybuilder",但是我非常确定我不是第一个遇到这种问题的人,因此我的问题是:

  • 您如何构造数据库查询?
  • C#是否提供一种简单的方法来动态构建查询?

我使用C#和Linq进行了类似的操作,以根据用户输入过滤日志条目(请参阅条件Linq查询):

1
2
3
4
5
6
7
8
9
10
11
12
13
IQueryable<Log> matches = m_Locator.Logs;

// Users filter
if (usersFilter)
    matches = matches.Where(l => l.UserName == comboBoxUsers.Text);

 // Severity filter
 if (severityFilter)
     matches = matches.Where(l => l.Severity == comboBoxSeverity.Text);

 Logs = (from log in matches
         orderby log.EventTime descending
         select log).ToList();

编辑:直到最后一条语句中的.ToList()才执行查询。


除非执行时间真的很重要,否则我将考虑重构业务逻辑,这种业务逻辑(经常)倾向于找到其到达数据层以及成千上万亿个存储proc的方式。在可维护性,可编辑性和附加性方面,我一直试图(作为C#程序员)将代码提升到业务层。

尝试挑选其他人的8000行SQL脚本不是我最喜欢的任务。

:)

// W


我来晚了,没有机会投票,但是我没有想到一个很好的解决方案:过程/函数与linq-to-object的结合。还是我想的to-xml或to-datatable。

在这种情况下,我一直处于这种状态,它具有巨大的动态构建的查询,虽然取得了令人印象深刻的成就,但是其复杂性却导致了一场噩梦。我有很多绿色评论来帮助可怜的汁液,这些汁液必须稍后再来理解。我当时使用的是经典的ASP,因此我几乎没有其他选择。

此后我要做的是功能/过程和linq的组合。通常,总的复杂性小于尝试在一个地方进行的复杂性。将您的某些条件传递给UDF,这将变得更加易于管理。这为您提供了易于管理和可理解的结果集。使用linq应用其余的区别。

您可以同时使用两者的优点:

  • 最多减少总记录
    在服务器上可能;得到尽可能多的
    疯狂加入照顾的
    服务器。数据库擅长于此
    东东。
  • Linq(针对对象等)虽然不那么强大,但擅长表达复杂的标准。因此将它用于各种可能的区别,这会增加代码的复杂性,但db的处理不会更好。在简化的标准化结果集上运行时,linq可以表达出复杂性,而不会降低性能。

如何决定在db中处理哪些条件以及使用linq处理哪些条件?用你的判断。如果您可以有效地处理复杂的数据库查询,则可以处理。部分是艺术,部分是科学。


Linq to SQL与System.Linq.Dynamic一起带来了一些不错的可能性。

我在这里发布了一些示例代码片段:
http://blog.huagati.com/res/index.php/2008/06/23/application-architecture-part-2-data-access-layer-dynamic-linq

...在这里:
http://episteme.arstechnica.com/eve/forums/a/tpc/f/6330927813/m/717004553931?r=777003863931#777003863931


我了解Linq的潜力,但是我还没有看到有人尝试对Ben建议的复杂性进行Linq查询。

the fairly complex sql statement (~10 joins, >10 sub selects, ~15-25 where conditions and GroupBy's)

有人有关于大型Linq查询的示例,以及有关其可管理性的任何评论吗?


值得考虑的是,是否可以将其实现为参数化的受支持过程并在数据库中对其进行优化,而不是在运行时通过LINQ或ORM动态生成SQL。通常,这会更好。我知道它有些过时,但有时是最有效的方法。


这是我要做的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public IQueryable<ClientEntity> GetClients(Expression<Func<ClientModel, bool>> criteria)
    {
        return (
            from model in Context.Client.AsExpandable()
            where criteria.Invoke(model)
            select new Ibfx.AppServer.Imsdb.Entities.Client.ClientEntity()
            {
                Id = model.Id,
                ClientNumber = model.ClientNumber,
                NameFirst = model.NameFirst,
                //more propertie here

            }
        );
    }

您传入的Expression参数将是将使用不同的WHERE子句,JOINS等构建的动态查询。此Expression将在运行时被调用并提供您所需的内容。

这里是如何调用它的示例:

1
2
3
4
5
6
public IQueryable<ClientEntity> GetClientsWithWebAccountId(int webAccountId)
    {
        var criteria = PredicateBuilder.True<ClientModel>();
        criteria = criteria.And(c => c.ClientWebAccount.WebAccountId.Equals(webAccountId));
        return GetClients(criteria);
    }

LINQ是必经之路。


查看http://sqlom.sourceforge.net。我认为它确实满足您的需求。


在http://www.blackbeltcoder.com/Articles/strings/a-sql-querybuilder-class上的QueryBuilder类上进行了一种实验性尝试。可能值得一看。


如果使用C#和.NET 3.5,并添加MS SQL Server,则LINQ to SQL绝对是可行的方法。如果您使用的不是该组合,则建议您使用ORM路由,例如nHibernate或Subsonic。


您可能需要考虑使用LINQ或类似这样的O / R映射器:http://www.llblgen.com/


查询方法动态对象

最新内容

相关内容

猜你喜欢