我在vb.net上做windows应用。我有客户对象包含保存方法。我如何生成插入查询?
我需要在关系数据库(SQL server)中保存对象。我需要知道插入的正确方法是哪种,即。在save方法中,我编写了SQL语句来保存对象。这是正确的方法吗?
由于
答案 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
我知道你已经听说过分离你的数据库代码是“正确的事情”,但我想你可能还想要一些更具体的理由,为什么你要这样构建你的代码:
答案 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在问什么。
您需要在“保存”方法中准确定义您正在做的事情
“保存”方法通常意味着两种情况都由程序处理。
更好的方法是(“创建”或“插入”)和(“更新”或“保存”)方法。
或者可能有一个处理两者的程序。