【问题标题】:Creating An Insert Statement -- Windows application Vb.Net创建插入语句——Windows 应用程序 Vb.Net
【发布时间】:2010-09-28 11:41:18
【问题描述】:

我在 vb.net 中做 windows 应用程序。我有客户对象包含保存方法。如何生成插入查询?

我需要将对象保存在关系数据库(SQL 服务器)中。我需要知道哪种是插入的正确方法,即。在 save 方法中,我编写了 SQL 语句来保存对象。方法对吗?

谢谢

【问题讨论】:

  • 您是在问如何在数据库中创建插入语句?如果有,是哪一个?
  • 您是在问如何(语法)编写 SQL 插入语句或如何以编程方式执行 SQL 语句?

标签: sql vb.net winforms thick-client


【解决方案1】:

SQL 的简单 INSERT 语句采用以下基本形式:

INSERT INTO [tablename] ( [column1], [column2], ... ) VALUES ( [value1], [value2], ...)

所以,我们显然需要了解您正在使用的数据库表:它有哪些列。我们还需要了解这个类:它有什么属性。最后,我们需要了解表列和类属性的数据类型,以及属性如何映射到列。对于非常简单的对象,名称和类型将对齐。但在其他情况下,您的类本身可能包含一个(或多个)集合,这意味着将数据插入多个表中。

确定了这一切之后,我们还需要两件事:数据库的连接信息(通常提炼成单个connection string)以及您是否担心您的类实例之前可能已保存,其中如果您想构建一个 UPDATE 语句而不是 INSERT。

假设您能够以令人满意的方式回答所有这些问题,您的 VB.Net 代码将如下所示(当然,在适当的情况下替换您的特定列、属性、类型和连接信息):

Public Class Customer
    Public Sub Save()
        DAL.SaveCustomer(Me)
    End Sub

    '   ...'

End Class

.

' a VB Module is a C# static class'
Public Module DAL 
    Private ConnString As String = "Your connection string here"

    Public Sub SaveCustomer(ByVal TheCustomer As Customer)
        Dim sql As String = "" & _
        "INSERT INTO [MyTable] (" & _
            "[column1], [column2], ..." & _
        ") VALUES (" & _
            "@Column1, @Column2, ... )"

        Using cn As New SqlConnection(ConnString), _
              cmd As New SqlCommand(sql, cn)

            cmd.Parameters.Add("@column1", SqlDbTypes.VarChar, 50).Value = TheCustomer.Property1
            cmd.Parameters.Add("@column2", SqlDbTypes.VarChar, 1000).Value = TheCustomer.Property2

            cn.Open()
            cmd.ExecuteNonQuery()
        End Using
    End Sub
End Module

我知道您已经听说分离出数据库代码是“正确的做法”,但我认为您可能还想了解一些更具体的原因,说明您希望以这种方式构建代码:

  • 您的连接字符串保存在一个位置,因此如果您的数据库服务器移动,您只需进行一项更改。如果这是它自己的程序集或配置文件,那就更好了。
  • 如果您曾经迁移到完全不同的数据库类型,您只需更改一个文件即可更新程序。
  • 如果您有一位开发人员或 DBA 特别擅长 sql,您可以让他完成应用程序这一部分的大部分维护工作。
  • 它使您的“真实”对象的代码更简单,因此在您犯了逻辑设计错误时更容易被发现。
  • 如果另一个应用程序想要与同一个数据库通信,则 DAL 代码最终可能会被重用。
  • 如果您使用 ORM 工具,大部分 DAL 代码都是为您编写的。

【讨论】:

    【解决方案2】:

    这里有一些问题。首先,你到底在哪里保存这个?您说 SQL,但它是 SQL Server、SQL Express 的实例、本地数据缓存 (SQL CE 3.5) 还是通过 Web 服务保存以与您的 SQL SERVER 对话。这些不同的数据源具有不同的连接选项/要求,对于 SQL CE,SQL 本身还涉及一些其他“陷阱”。

    其次,您确定要将数据保存到 SQL Server 等关系数据存储中吗?考虑一下,您可以改用 XML、数据文件(文本、CSV 等)甚至自定义二进制文件类型。

    由于您使用的是 Windows 应用程序,因此您可以选择在何处以及如何保存数据。在您知道要将数据放在哪里之前,我们很难为您提供帮助。

    【讨论】:

      【解决方案3】:

      我同意 Mike Hofer 的观点。将您的对象检索和持久化的类与您的业务类分开是拥有灵活和健壮设计的关键。这是您希望在 GUI 或业务层中看到的代码:

      //Populate Customer Objects List with data
      IList<Customer> customerList = new List<Customer>()
      Customer newCustomer1 = new Customer();
      newCustomer.Name = "New Name"
      newCustomer.email ="abcd@abcd.com"
      customerList.Add(newCustomer1)
      
      //DAL calls
      DataAccessClass dalClass = new DataAccessClass ();
      dalClass.InsertCustomers(customerList);
      

      在您的 DALClass 中应该有一个名为 InsertCustomers(IList customers) 的方法,它应该有以下代码:

            Public Function InsertCustomers(ByVal objectList As IList(Of Customer)) As Integer
              Dim command As IDbCommand = Nothing
              Dim rowsAffected As Integer = 0
              Dim connection As IDbConnection = New System.Data.SqlClient.SqlConnection(Me.ConnectionString)
              Try 
                  connection.Open
                  Dim e As IEnumerator = objectList.GetEnumerator
      
                  Do While e.MoveNext
      
                      command = connection.CreateCommand
                      command.CommandText = "insert into dbo.Customer(CustomerID,CustomerGUID,RegisterDate,Password,SiteID,Las"& _ 
                          "tName,FirstName,Email,Notes,BillingEqualsShipping,BillingLastName) values (@Cust"& _ 
                          "omerID,@CustomerGUID,@RegisterDate,@Password,@SiteID,@LastName,@FirstName,@Email"& _ 
                          ",@Notes,@BillingEqualsShipping,@BillingLastName)"
                      System.Console.WriteLine("Executing Query: {0}", command.CommandText)
                      Dim paramCustomerID As IDbDataParameter = command.CreateParameter
                      paramCustomerID.ParameterName = "@CustomerID"
                      command.Parameters.Add(paramCustomerID)
                      Dim paramCustomerGUID As IDbDataParameter = command.CreateParameter
                      paramCustomerGUID.ParameterName = "@CustomerGUID"
                      command.Parameters.Add(paramCustomerGUID)
                      Dim paramRegisterDate As IDbDataParameter = command.CreateParameter
                      paramRegisterDate.ParameterName = "@RegisterDate"
                      command.Parameters.Add(paramRegisterDate)
                      Dim paramPassword As IDbDataParameter = command.CreateParameter
                      paramPassword.ParameterName = "@Password"
                      command.Parameters.Add(paramPassword)
                      Dim paramSiteID As IDbDataParameter = command.CreateParameter
                      paramSiteID.ParameterName = "@SiteID"
                      command.Parameters.Add(paramSiteID)
                      Dim paramLastName As IDbDataParameter = command.CreateParameter
                      paramLastName.ParameterName = "@LastName"
                      command.Parameters.Add(paramLastName)
                      Dim paramFirstName As IDbDataParameter = command.CreateParameter
                      paramFirstName.ParameterName = "@FirstName"
                      command.Parameters.Add(paramFirstName)
                      Dim paramEmail As IDbDataParameter = command.CreateParameter
                      paramEmail.ParameterName = "@Email"
                      command.Parameters.Add(paramEmail)
                      Dim paramNotes As IDbDataParameter = command.CreateParameter
                      paramNotes.ParameterName = "@Notes"
                      command.Parameters.Add(paramNotes)
                      Dim paramBillingEqualsShipping As IDbDataParameter = command.CreateParameter
                      paramBillingEqualsShipping.ParameterName = "@BillingEqualsShipping"
                      command.Parameters.Add(paramBillingEqualsShipping)
                      Dim paramBillingLastName As IDbDataParameter = command.CreateParameter
                      paramBillingLastName.ParameterName = "@BillingLastName"
                      command.Parameters.Add(paramBillingLastName)
                      Dim modelObject As Customer = CType(e.Current,Customer)
                      paramCustomerID.Value = modelObject.CustomerID
                      paramCustomerGUID.Value = modelObject.CustomerGUID
                      paramRegisterDate.Value = modelObject.RegisterDate
                      If IsNothing(modelObject.Password) Then
                          paramPassword.Value = System.DBNull.Value
                      Else
                          paramPassword.Value = modelObject.Password
                      End If
                      paramSiteID.Value = modelObject.SiteID
                      If IsNothing(modelObject.LastName) Then
                          paramLastName.Value = System.DBNull.Value
                      Else
                          paramLastName.Value = modelObject.LastName
                      End If
                      If IsNothing(modelObject.FirstName) Then
                          paramFirstName.Value = System.DBNull.Value
                      Else
                          paramFirstName.Value = modelObject.FirstName
                      End If
                      If IsNothing(modelObject.Email) Then
                          paramEmail.Value = System.DBNull.Value
                      Else
                          paramEmail.Value = modelObject.Email
                      End If
                      If IsNothing(modelObject.Notes) Then
                          paramNotes.Value = System.DBNull.Value
                      Else
                          paramNotes.Value = modelObject.Notes
                      End If
                      paramBillingEqualsShipping.Value = modelObject.BillingEqualsShipping
                      If IsNothing(modelObject.BillingLastName) Then
                          paramBillingLastName.Value = System.DBNull.Value
                      Else
                          paramBillingLastName.Value = modelObject.BillingLastName
                      End If
                      rowsAffected = (rowsAffected + command.ExecuteNonQuery)
      
                  Loop
              Finally
                  connection.Close
                  CType(connection,System.IDisposable).Dispose
              End Try
              Return rowsAffected
          End Function
      

      手工编写 DAL 代码很痛苦,但您可以完全控制 DAL、SQL 和映射代码,并且将来更改其中任何一个都将变得轻而易举。

      如果您不想手动编写所有 DAL 代码,您可以使用像 Orasis Mapping Studio 这样的 CodeGenerator 来生成与所示完全相同的代码,而无需编写任何内容。您只需要在工具中构建 SQL,将属性映射到参数即可。它将为您生成所有其余部分。

      祝你好运,愉快的 DAL 编码!

      【讨论】:

        【解决方案4】:

        我和斯蒂芬·赖顿在一起。这里有很多变数,还有很多悬而未决的问题。如果是 SQL,它甚至是 SQL 的 Microsoft 方言吗?是甲骨文吗? MySQL?还有什么?

        无论如何,我个人的偏好是尽可能避免在应用程序中构建 SQL,并调用存储过程,即使对于插入和更新也是如此。然后我将过程的参数传递给 ADO.NET 命令对象。我脑子里有一个疯狂的想法,即 SQL 属于数据库。也许这来自于我在互联网时代花费大量时间调试将 SQL 字符串拼接在一起的可怕编写的 ASP 代码。 (再也不会了。)

        如果您觉得绝对有必要这样做,请参加 System.Text.StringBuilder 课程。学习它。爱它。让它成为你最好的朋友。

        更新: 看到您的回复,我现在看到您正在使用 SQL Server。这会让事情变得更好。

        我建议将您的 SQL 代码分离到一个单独的类中,远离实际的业务类。有些人可能不同意这一点,但它会使课程的目的保持清晰。 (见Separation of Concerns。)

        您希望让您的业务对象处理业务逻辑,并让一个单独的类处理将数据输入和输出数据库的工作。这样,如果您对序列化逻辑有疑问,您就可以更好地了解在哪里查找,并且大大减少了处理业务逻辑的机会。它还使您的应用程序更易于理解。

        在编写更多课程方面付出一点前期努力会在未来获得巨大的回报。

        但这只是我的意见。

        【讨论】:

          【解决方案5】:

          我更喜欢 Mike Hofer 的想法,在 SQL Server 端有一个存储过程来处理实际的数据更新,并有一个单独的类来包装对这些存储过程的调用。 只是我的 0.02 美元

          【讨论】:

          • 根据我的经验,这取决于系统:如果数据库存在供单个应用程序使用,我更喜欢与应用程序一起使用的 sql 代码。如果它是一个“企业”数据库服务器,我更喜欢将代码与数据库一起使用。
          【解决方案6】:

          不太清楚 OP 在问什么。

          您需要在“保存”方法中准确定义您在做什么

          • 如果您在 Save 方法中创建新记录,则需要使用 INSERT 语句。
          • 如果您在 Save 方法中更新现有记录,则需要使用 UPDATE 语句。

          “保存”方法通常意味着这两种情况都由过程处理。

          更好的方法是使用 ("Create" 或 "Insert") 和 ("Update" 或 "Save") 方法。

          或者也许有一个程序可以同时处理这两种情况。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-10-25
            • 2017-07-27
            • 1970-01-01
            • 2019-02-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-08-20
            相关资源
            最近更新 更多