创建插入语句 - Windows应用程序Vb.Net

时间:2008-12-26 17:56:03

标签: sql vb.net winforms thick-client

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

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

由于

6 个答案:

答案 0 :(得分:4)

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

我知道你已经听说过分离你的数据库代码是“正确的事情”,但我想你可能还想要一些更具体的理由,为什么你要这样构建你的代码:

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

答案 1 :(得分:1)

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

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

由于您正在使用Windows应用程序,因此您可以选择保存数据的位置和方式。在您知道要将数据放在何处之前,我们很难帮您这样做。

答案 2 :(得分:1)

我同意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客户)的方法,它应该有以下代码:

      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编码!

答案 3 :(得分:0)

我和Stephen Wrighton在一起。这里有很多变量,还有很多未解决的问题。如果它是SQL,它甚至是微软的SQL方言吗?是甲骨文吗? MySQL的?还有别的吗?

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

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

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

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

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

在撰写更多课程时,我们需要付出一点努力才能获得巨大回报。

但这只是我的意见。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

不太确定OP在问什么。

您需要在“保存”方法中准确定义您正在做的事情

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

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

更好的方法是(“创建”或“插入”)和(“更新”或“保存”)方法。

或者可能有一个处理两者的程序。