代码之家  ›  专栏  ›  技术社区  ›  MadBoy

这个方法是从C#获取SQL值的好方法吗?

  •  4
  • MadBoy  · 技术社区  · 16 年前

    我有一个小方法,我用它从SQL中获取数据。我要么用 varSearch = "" varSearch = "something" . 我想知道以这种方式编写方法是最好的,还是最好将它分成两个方法(通过重载),或者我可以以某种方式将整个方法参数化 WHERE 小条款?

    private void sqlPobierzKontrahentDaneKlienta(ListView varListView, string varSearch) {
            varListView.BeginUpdate();
            varListView.Items.Clear();
            string preparedCommand;
            if (varSearch == "") {
                preparedCommand = @"
                    SELECT t1.[KlienciID],
                    CASE WHEN t2.[PodmiotRodzaj] = 'Firma' THEN
                              t2.[PodmiotFirmaNazwa] ELSE 
                              t2.[PodmiotOsobaNazwisko] + ' ' + t2.[PodmiotOsobaImie] END AS 'Nazwa'
                    FROM [BazaZarzadzanie].[dbo].[Klienci] t1
                    INNER JOIN [BazaZarzadzanie].[dbo].[Podmioty] t2
                    ON t1.[PodmiotID] = t2.[PodmiotID]
                    ORDER BY t1.[KlienciID]";
            } else {
                preparedCommand = @"
                    SELECT t1.[KlienciID],
                    CASE WHEN t2.[PodmiotRodzaj] = 'Firma' THEN
                              t2.[PodmiotFirmaNazwa] ELSE 
                              t2.[PodmiotOsobaNazwisko] + ' ' + t2.[PodmiotOsobaImie] END AS 'Nazwa'
                    FROM [BazaZarzadzanie].[dbo].[Klienci] t1
                    INNER JOIN [BazaZarzadzanie].[dbo].[Podmioty] t2
                    ON t1.[PodmiotID] = t2.[PodmiotID]
                    WHERE t2.[PodmiotOsobaNazwisko] LIKE @searchValue OR t2.[PodmiotFirmaNazwa] LIKE @searchValue OR t2.[PodmiotOsobaImie] LIKE @searchValue
                    ORDER BY t1.[KlienciID]";
            }
            using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
            using (SqlCommand sqlQuery = new SqlCommand(preparedCommand, varConnection)) {
                sqlQuery.Parameters.AddWithValue("@searchValue", "%" + varSearch + "%");
                using (SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader())
                    if (sqlQueryResult != null) {
                        while (sqlQueryResult.Read()) {
                            string varKontrahenciID = sqlQueryResult["KlienciID"].ToString();
                            string varKontrahent = sqlQueryResult["Nazwa"].ToString();
                            ListViewItem item = new ListViewItem(varKontrahenciID, 0);
                            item.SubItems.Add(varKontrahent);
                            varListView.Items.AddRange(new[] {item});
                        }
                    }
            }
            varListView.EndUpdate();
        }
    
    5 回复  |  直到 16 年前
        1
  •  6
  •   dcp    16 年前

    更好的方法实际上是使用存储过程,而不是将SQL硬编码到应用程序中。可以将where子句参数传递给存储过程,并在数据库端处理逻辑。

    这种方法还提供了一个优势,即如果您在另一个应用程序(例如JAVA应用程序)中需要此逻辑,则该逻辑将集中在数据库中,因此您不必再次重写它。

        2
  •  3
  •   TomTom    16 年前

    • 完全没有DAL—这意味着您的SQL代码被粘贴在所有表单上。糟糕的维护—至少将所有SQL处理放在一个类中。

    • 这是许多手动编写的代码,因此它的性能很差(如:程序员性能)。请看BLToolkit,了解如何在运行时生成所有代码(从带有SQL和抽象方法的属性库生成,带有实际方法的子类是字节码生成的)。

    也就是说,除非我能说服您使用像NHibernate这样的真正的数据访问层/ORM。

        3
  •  0
  •   Midhat    16 年前

         string preparedCommandTemplate = @"
                            SELECT t1.[KlienciID],
                            CASE WHEN t2.[PodmiotRodzaj] = 'Firma' THEN
                                      t2.[PodmiotFirmaNazwa] ELSE 
                                      t2.[PodmiotOsobaNazwisko] + ' ' + t2.[PodmiotOsobaImie] END AS 'Nazwa'
                            FROM [BazaZarzadzanie].[dbo].[Klienci] t1
                            INNER JOIN [BazaZarzadzanie].[dbo].[Podmioty] t2
                            ON t1.[PodmiotID] = t2.[PodmiotID] {0}
                            ORDER BY t1.[KlienciID]";
    string whereClause="WHERE t2.[PodmiotOsobaNazwisko] LIKE @searchValue OR t2.[PodmiotFirmaNazwa] LIKE @searchValue OR t2.[PodmiotOsobaImie] LIKE @searchValue"
    
     if (string.Emtpy.Equals(varSearch )) {
                preparedCommand = string.Format(preparedCommandTemplate,string.Empty)
            } else {
                preparedCommand = string.Format(preparedCommandTemplate,whereCaluse)
    
            }
    
        4
  •  0
  •   Tom Cabanski    16 年前

    如果不想使用存储过程,至少要参数化where子句。这种代码很快就会失控。我还将考虑使用免费文本索引或类似LuxeN.NET之类的方法来实现跨多个字段的“类”搜索。

        5
  •  0
  •   Ronald Wildenberg    16 年前

    如果您想继续在代码中使用硬编码的SQL语句(而不是切换到LINQ2SQL、Entity Framework或其他ORM工具),那么 我们要做的是将where子句作为参数添加到方法中(如果这就是“参数化where子句”的意思)。这使得使用此方法的客户机依赖于您的数据访问技术(在本例中是SQL数据库)。

    比较以下两个调用:

    sqlPobierzKontrahentDaneKlienta(lv, "something");
    

    sqlPobierzKontrahentDaneKlienta(lv,
        "WHERE t2.[PodmiotOsobaNazwisko] LIKE '%something%' OR " +
        "      t2.[PodmiotFirmaNazwa] LIKE '%something%' OR " +
        "      t2.[PodmiotOsobaImie] LIKE '%something%'")
    

    哪一个看起来更好?