1

私はvb.netでWindowsアプリケーションを実行しています。顧客オブジェクトにsaveメソッドが含まれています。挿入クエリを生成するにはどうすればよいですか?

オブジェクトをリレーショナルデータベース(SQLサーバー)に保存する必要があります。挿入を行う正しい方法はどれかを知る必要があります。saveメソッド内に、オブジェクトを保存するためのSQLステートメントを記述しました。それは正しい方法ですか?

ありがとう

4

6 に答える 6

4

SQL の単純な INSERT ステートメントは、次の基本的な形式を取ります。

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

したがって、使用しているデータベース テーブルについて知る必要があることは明らかです。クラスについても知る必要があります。つまり、クラスが持つプロパティです。最後に、テーブルの列とクラス プロパティのデータ型、およびプロパティが列にどのようにマップされるかについて知る必要があります。非常に単純なオブジェクトの場合、名前とタイプは単純に並べられます。ただし、クラス自体にコレクション (または複数) が含まれている場合もあります。これは、データを複数のテーブルに挿入することを意味します。

データベースの接続情報 (通常は 1 つの接続文字列に要約されます) と、クラス インスタンスが以前に保存されている可能性があることを懸念しているかどうか。 INSERT ステートメントではなく UPDATE ステートメントを作成します。

そのすべてに満足のいく方法で答えることができると仮定すると、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 つ行うだけで済みます。これが独自のアセンブリまたは構成ファイルである場合はさらに優れています。
  • まったく異なるデータベース タイプに移動した場合でも、プログラムを更新するために 1 つのファイルを変更するだけで済みます。
  • SQL に特に優れた開発者または DBA が 1 人いる場合は、アプリのこの部分のほとんどのメンテナンスを彼に任せることができます。
  • これにより、「実際の」オブジェクトのコードが単純になるため、論理的な設計エラーが発生したときに簡単に見つけることができます。
  • 別のアプリケーションが同じデータベースと通信したい場合、DAL コードは最終的に再利用可能になる可能性があります。
  • ORM ツールを使用すると、ほとんどの DAL コードが自動的に作成されます。
于 2008-12-26T19:25:24.737 に答える
1

私はマイク・ホーファーに同意します。オブジェクトの取得と永続化を行うクラスをビジネス クラスから分離しておくことは、柔軟で堅牢な設計を実現するための鍵です。これは、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 コーディングをお楽しみください!

于 2008-12-26T21:04:48.720 に答える
1

ここにはいくつかの問題があります。まず、これを正確にどこに保存していますか?SQL と言いますが、それは SQL Server、SQL Express のインスタンス、ローカル データ キャッシュ (SQL CE 3.5)、または SQL SERVER と対話するための Web サービス経由の保存ですか。これらのさまざまなデータ ソースには、さまざまな接続オプション/要件があり、SQL CE の場合、SQL 自体に関連する他のいくつかの「落とし穴」があります。

次に、SQL Server などのリレーショナル データストアにデータを保存しますか? 代わりに、XML、データ ファイル (テキスト、CSV など)、またはカスタム バイナリ ファイル タイプを使用することもできます。

Windows アプリケーションで作業しているため、データを保存する場所と方法について多くのオプションがあります。データをどこに置きたいかがわかるまでは、そうするのを手伝うのは難しいでしょう。

于 2008-12-26T18:09:24.830 に答える
0

OPが何を求めているのかよくわかりません。

「保存」メソッドで実行していることを正確に定義する必要があります

  • Saveメソッドで新しいレコードを作成する場合は、INSERTステートメントを使用する必要があります。
  • Saveメソッドで既存のレコードを更新する場合は、UPDATEステートメントを使用する必要があります。

「保存」メソッドは、通常、両方のケースがプロシージャによって処理されることを意味します。

より良い方法は、(「作成」または「挿入」)および(「更新」または「保存」)メソッドを持つことです。

または、両方を処理する1つのプロシージャがあるかもしれません。

于 2008-12-26T23:28:08.070 に答える
0

SQL Server 側にストアド プロシージャを配置して実際のデータ更新を処理し、それらのストアド プロシージャへの呼び出しをラップする別のクラスを用意するというマイク ホーファーのアイデアを好みます。ちょうど私の 0.02$

于 2008-12-26T19:25:50.587 に答える
0

私はスティーブン・ライトンと一緒です。ここには多くの変数があり、多くの未回答の質問があります。それが SQL の場合、SQL の Microsoft 方言ですか? オラクルですか?MySQL? 他の何か?

いずれにせよ、私の個人的な好みは、可能であればアプリケーションで SQL を構築することを避け、挿入と更新であってもストアド プロシージャを呼び出すことです。次に、プロシージャの引数を ADO.NET コマンド オブジェクトに渡します。SQL はデータベースに属しているという非常識な考えが頭の中にあります。おそらくそれは、Dot Com 時代にさかのぼって SQL 文字列を繋ぎ合わせた恐ろしく書かれた ASP コードのデバッグに費やしたすべての時間から来ているのでしょう。(二度と。)

そうすることが絶対に必要だと思われる場合は、System.Text.StringBuilderクラスに対応してください。学べ。大好きです。それをあなたの親友にしてください。

更新: あなたの回答を見て、SQL Server を使用していることがわかります。それは物事をはるかに良くします。

実際のビジネス クラスから離れて、SQL コードを別のクラスに分離することをお勧めします。それに同意しない人もいるかもしれませんが、クラスの目的を明確に保つことができます。(関心の分離を参照してください。)

ビジネス オブジェクトでビジネス ロジックを処理し、別のクラスでデータベースにデータを出し入れする作業を処理する必要があります。そうすれば、シリアライゼーション ロジックに問題がある場合に、どこを見ればよいかがはるかに分かりやすくなり、ビジネス ロジックに問題が発生する可能性が大幅に減少します。また、アプリケーションをより理解しやすくします。

さらにいくつかのクラスを作成するための少し前もっての努力は、将来的に大きな成果をもたらします。

しかし、それは私の意見です。

于 2008-12-26T18:21:09.627 に答える