Duwamish7分析——结帐

用户登录后,“Checkout”(结帐)ASP.NET 页上的功能使用户能够完成购物过程并结束交易。
实现
“Checkout”(结帐)页使用下面的 ASP.NET 文件和 C# 或 Visual Basic .NET 代码隐藏文件:
Checkout.aspx
Checkout.aspx.cs
Checkout.aspx.vb
注意   有关 ASP.NET 代码隐藏的更多信息,请参见创建 ASP.NET Web 应用程序。
序列关系图

过程概述
用户从 ASP.NET 页顶部选择购物车选项或者在图书选区选择了“Add To Cart”(添加到购物车)按钮后,应用程序显示“shopping cart”(购物车)页。有关更多信息,请参见购物车。若要继续运行到结帐,用户须单击“Proceed to Checkout”(前进到结帐)链接。关联的 Forms 身份验证或者调用要登录的用户,或者向已登录的用户显示结帐过程的步骤。有关更多信息,请参见登录。当用户登录时,用户的帐户信息(地址等)保持在会话状态中。所有的结帐步骤都是同一 ASP.NET 页的一部分。下面的 Web 控制面板指导每个用户完成结帐步骤:
Duwamish7.Web.Checkout.ShippingPanel
加载此页时,ASP.NET Page_Load 方法用包含在会话状态(在登录过程中获得)中和通过 Cart Helper 类访问的值填充“Shipping”(发货)Web 控制面板。
Duwamish7.Web.Checkout.PaymentPanel
“Payment Details”(付款详细信息)Web 控制面板要求用户提供详细的信用卡信息。然后通过 ShoppingCart.SetPayment 方法将付费信息复制到 Cart Helper 类。
Duwamish7.Web.Checkout.SummaryPanel
结帐过程的最后一步是确认订单。当用户单击“Confirm”(确认)按钮时,Web 层的 Duwamish7.Web.Checkout.NextImageButton 方法调用 Cart Helper 类的 Duwamish7.Web.Cart.AddOrder 方法。下一步,Duwamish7.Web.Cart.AddOrder 方法调用业务外观层的 Duwamish7.BusinessFacade.OrderSystem.AddOrder 方法。接着,Duwamish7.BusinessFacade.OrderSystem.AddOrder 方法调用业务规则层的 Duwamish7.BusinessRules.Order.InsertOrder 方法。下一步,它调用数据访问层的 Duwamish7.DataAccess.Orders.InsertOrderDetail 方法。Duwamish7.DataAccess.Orders.InsertOrderDetail 方法调用 InsertSale 存储过程 (SPROC),而后者将交易保存到数据库。
安全说明   Duwamish 7.0 示例应用程序将信用卡号以明文形式存储在 SQL 数据库中。虽然这些卡号受 SQL Server 安全性的保护,但在实际的应用程序中,还可以包括其他的安全措施,比如在将卡号存储在数据库中之前对它们进行加密。您的最终决定取决于应用程序的信用卡处理系统的实现方式。有关加密的更多信息,请参见 System.Security.Cryptography 命名空间(Visual J# 语法)。
有关 ASP.NET 面板的更多信息,请参见 Panel 类。
结构决策
Cart 类收集 Web 层上的订单所需要的信息,然后通过业务外观层提交完成的订单。这维护了无状态的业务外观层以提高可伸缩性。另一种方法是将购物车保持到 SQL。这样可避免在会话超时时丢失购物车的可能性,并且允许用户以后重新连接自己的购物车。
要点
插入订单是调用业务规则的少数几个地方之一。
若要查找适用于本主题中特定层的源代码,请单击相应的链接:
业务外观源 | 业务规则源代码 | 数据访问源代码 | SPROC
Web 源代码
Duwamish7.Web.Checkout.NextImageButton 方法源代码的默认位置是 [安装 Visual Studio .NET 的驱动器号]:/Program Files/Microsoft Visual Studio .NET 2003/Enterprise Samples/Duwamish 7.0 CS/Web/Secure/Checkout.aspx.cs 文件。Duwamish7.Web.Cart.Addorder 方法的默认位置是 [安装 Visual Studio .NET 的驱动器号]:/Program Files/Microsoft Visual Studio .NET 2003/Enterprise Samples/Duwamish 7.0 CS/Web/Cart.cs 文件。
注意   如果安装了 Visual Basic .NET 版本,则 Duwamish 7.0 VB 将替换路径中的 Duwamish 7.0 CS,其文件名相同,但扩展名是 vb 而不是 cs。
Duwamish7.Web.Checkout.NextImageButton:
[C#]
/// <summary>
///     Move to the next step in the checkout process.
///     <param name="sender">The source of the event.</param>
///     <param name="e">An EventArgs that contains the event data.</param>
/// </summary>
public void NextImageButton_Click (object sender, System.Web.UI.ImageClickEventArgs e)
{
    bool stepSuccess = false;
//code removed for sake of brevity
    switch (stage)
    {
        case 0:
            stepSuccess = ValidateShipping();
            break;
           
        case 1:
            stepSuccess = ValidatePayment();
            break;
           
        case 2:
            stepSuccess = SubmitOrder();
            break;
    }
   
    if (stepSuccess)
    {
        ++stage;
    }
   
    SetPanelDisplay();
}
[Visual Basic .NET]
'----------------------------------------------------------------
' Sub NextImageButton_Click:
'   Move to the next step in the checkout process.
' Parameters:
'   [in] sender: not used
'   [in] e: not used
'----------------------------------------------------------------
Private Sub NextImageButton_Click(ByVal sender As System.Object, ByVal e As System.Web.UI.ImageClickEventArgs)
    Dim stepSuccess As Boolean
'code removed for sake of brevity
    Select Case stage
        Case 0
            stepSuccess = ValidateShipping()
           
        Case 1
            stepSuccess = ValidatePayment()
           
        Case 2
            stepSuccess = SubmitOrder()
           
    End Select
   
    If stepSuccess = True Then
        stage = stage + 1
    End If
   
    SetPanelDisplay()
End Sub
Duwamish7.Web.Cart.Addorder 方法:
[C#]
/// <summary>
///     Add the order in OrderData and returns the transaction id.
///     <exception> class='System.ApplicationException'>
///         The cartOrderData is null.
///     </exception>
/// </summary>
public void AddOrder()
{
    ApplicationAssert.CheckCondition(cartOrderData != null, "Order requires data", ApplicationAssert.LineNumber);
    //Write trace log.
    ApplicationLog.WriteTrace("Duwamish7.Web.Cart.AddOrder:/r/nCustomerId: " +
                              cartOrderData.Tables[OrderData.CUSTOMER_TABLE].Rows[0][OrderData.PKID_FIELD].ToString());
    cartOrderData = (new OrderSystem()).AddOrder(cartOrderData);
}
[Visual Basic .NET]
'----------------------------------------------------------------
' Function AddOrder:
'   Add the order in OrderData.
' PreConditions:
'   cartOrderData is not Nothing
'----------------------------------------------------------------
Public Sub AddOrder()
    ApplicationAssert.CheckCondition(Not cartOrderData Is Nothing, "Order requires data", ApplicationAssert.LineNumber)

    '
    ' Write trace log.
    '
    ApplicationLog.WriteTrace("Duwamish7.Web.Cart.AddOrder:" & ControlChars.CrLf & _
                              "CustomerId: " & CStr(cartOrderData.Tables(OrderData.CUSTOMER_TABLE).Rows(0).Item(OrderData.PKID_FIELD)))           
                             
    cartOrderData = (New OrderSystem()).AddOrder(cartOrderData)
End Sub
业务外观源代码
Duwamish7.BusinessFacade.OrderSystem.Addorder 方法源代码的默认位置是 [安装 Visual Studio .NET 的驱动器号]:/Program Files/Microsoft Visual Studio .NET 2003/Enterprise Samples/Duwamish 7.0 CS/Business/Facade/OrderSystem.cs 文件。
注意   如果安装了 Visual Basic .NET 版本,则 Duwamish 7.0 VB 将替换路径中的 Duwamish 7.0 CS,其文件名相同,但扩展名是 vb 而不是 cs。
Duwamish7.BusinessFacade.OrderSystem.Addorder 方法:
[C#]
/// <summary>
///     Add an order and return the transaction id.
///     <param name="order">The order that is being worked on.</param>
///     <retvalue>The order that has just been added.</retvalue>
///     <exception> class='System.ApplicationException'>
///         The order is null.
///     </exception>
/// </summary>
public OrderData AddOrder(OrderData order)
{
    //
    // Check preconditions
    //
    ApplicationAssert.CheckCondition(order != null, "Order is required", ApplicationAssert.LineNumber);
   
    (new BusinessRules.Order()).InsertOrder(order);
    return order;
}
[Visual Basic .NET]
'----------------------------------------------------------------
' Function AddOrder:
'   Add an order and return the transaction id
' Returns:
'   The order that has just been added        
' Parameters:
'   [in]   order:   the order that is being added       
' Throws:
'   PreConditionException
' PreConditions:
'   order is Not Nothing
'----------------------------------------------------------------
Public Function AddOrder(ByVal order As OrderData) As OrderData
    '
    ' Check preconditions
    '
    ApplicationAssert.CheckCondition(Not order Is Nothing, "Order is required", ApplicationAssert.LineNumber)
                                  
    Dim brOrder As New BusinessRules.Order
    brOrder.InsertOrder(order)          
   
    AddOrder = order
End Function
业务规则源代码
Duwamish7.BusinessRules.Order.InsertOrder 方法源代码的默认位置是 [安装 Visual Studio .NET 的驱动器号]:/Program Files/Microsoft Visual Studio .NET 2003/Enterprise Samples/Duwamish 7.0 CS/Business/Rules/Order.cs 文件。
注意   如果安装了 Visual Basic .NET 版本,则 Duwamish 7.0 VB 将替换路径中的 Duwamish 7.0 CS,其文件名相同,但扩展名是 vb 而不是 cs。
Duwamish7.BusinessRules.Order.InsertOrder 方法:
[C#]
/// <summary>
///     Inserts an order.
///     <param name="order">The order insert.</param>
///     <retvalue>true if successful: false otherwise.</retvalue>
/// </summary>
public bool InsertOrder(OrderData order)
{   
    //
    // Assume it's good
    //
    bool isValid = true;
    //           
    // Validate order summary
    //
    DataRow summaryRow = order.Tables[OrderData.ORDER_SUMMARY_TABLE].Rows[0];
   
    summaryRow.ClearErrors();

    if (CalculateShipping(order) != (Decimal)(summaryRow[OrderData.SHIPPING_HANDLING_FIELD]))
    {
        summaryRow.SetColumnError(OrderData.SHIPPING_HANDLING_FIELD, OrderData.INVALID_FIELD);
        isValid = false;
    }

    if (CalculateTax(order) != (Decimal)(summaryRow[OrderData.TAX_FIELD]))
    {
        summaryRow.SetColumnError(OrderData.TAX_FIELD, OrderData.INVALID_FIELD);
        isValid = false;
    }
    //   
    // Validate shipping info
    //
    isValid &= IsValidField(order, OrderData.SHIPPING_ADDRESS_TABLE, OrderData.SHIP_TO_NAME_FIELD, 40);
    //
    // Validate payment info
    //
    DataRow paymentRow = order.Tables[OrderData.PAYMENT_TABLE].Rows[0];
   
    paymentRow.ClearErrors();
   
    isValid &= IsValidField(paymentRow, OrderData.CREDIT_CARD_TYPE_FIELD, 40);
    isValid &= IsValidField(paymentRow, OrderData.CREDIT_CARD_NUMBER_FIELD,  32);
    isValid &= IsValidField(paymentRow, OrderData.EXPIRATION_DATE_FIELD, 30);
    isValid &= IsValidField(paymentRow, OrderData.NAME_ON_CARD_FIELD, 40);
    isValid &= IsValidField(paymentRow, OrderData.BILLING_ADDRESS_FIELD, 255);
    //
    // Validate the order items and recalculate the subtotal
    //
    DataRowCollection itemRows = order.Tables[OrderData.ORDER_ITEMS_TABLE].Rows;
   
    Decimal subTotal = 0;
   
    foreach (DataRow itemRow in itemRows)
    {
        itemRow.ClearErrors();
       
        subTotal += (Decimal)(itemRow[OrderData.EXTENDED_FIELD]);
       
        if ((Decimal)(itemRow[OrderData.PRICE_FIELD]) <= 0)
        {
            itemRow.SetColumnError(OrderData.PRICE_FIELD, OrderData.INVALID_FIELD);
            isValid = false;
        }

        if ((short)(itemRow[OrderData.QUANTITY_FIELD]) <= 0)
        {
            itemRow.SetColumnError(OrderData.QUANTITY_FIELD, OrderData.INVALID_FIELD);
            isValid = false;
        }
    }
    //
    // Verify the subtotal
    //
    if (subTotal != (Decimal)(summaryRow[OrderData.SUB_TOTAL_FIELD]))
    {
        summaryRow.SetColumnError(OrderData.SUB_TOTAL_FIELD, OrderData.INVALID_FIELD);
        isValid = false;
    }

    if ( isValid )
    {
        using (DataAccess.Orders ordersDataAccess = new DataAccess.Orders())
        {
            return (ordersDataAccess.InsertOrderDetail(order)) > 0;
        }
    }
    else
        return false;
}
[Visual Basic .NET]
'----------------------------------------------------------------
' Function InsertOrder:
'   Inserts an order.
' Returns:
'   boolean:  Status of attempted order insert.
' Parameters:
'   [in]  order: The order.
'----------------------------------------------------------------
Public Function InsertOrder(ByVal order as OrderData) As Boolean
    Dim isValid As Boolean = True

    '
    ' Check Preconditions
    '
    ApplicationLog.WriteTrace("Duwamish7.BusinessRules.order.InsertOrder:" & ControlChars.CrLf & _
                              "CustomerId: " & CStr(order.Tables(OrderData.CUSTOMER_TABLE).Rows(0).Item(OrderData.PKID_FIELD)))
    '
    ' Validate order summary
    '
    Dim summaryRow As DataRow = order.Tables(OrderData.ORDER_SUMMARY_TABLE).Rows(0)
    summaryRow.ClearErrors
    With summaryRow
        .ClearErrors
        If CalculateShipping(order) <> CType(.Item(OrderData.SHIPPING_HANDLING_FIELD), Decimal) Then
            .SetColumnError(OrderData.SHIPPING_HANDLING_FIELD, OrderData.INVALID_FIELD)
            isValid = True
        End If

        If CalculateTax(order) <> CType(.Item(OrderData.TAX_FIELD),Decimal) Then
            .SetColumnError(OrderData.TAX_FIELD, OrderData.INVALID_FIELD)
            isValid = True
        End If
       
    End With
      
    '
    ' Validate shipping info
    '
    isValid = IsValidField(order, OrderData.SHIPPING_ADDRESS_TABLE, OrderData.SHIP_TO_NAME_FIELD, 40) AND isValid

    '
    ' Validate payment info
    '
    Dim paymentRow As DataRow = order.Tables(OrderData.PAYMENT_TABLE).Rows(0)
   
    paymentRow.ClearErrors
    isValid = IsValidField(paymentRow, OrderData.CREDIT_CARD_TYPE_FIELD, 40) AND isValid
    isValid = IsValidField(paymentRow, OrderData.CREDIT_CARD_NUMBER_FIELD,  32) AND isValid
    isValid = IsValidField(paymentRow, OrderData.EXPIRATION_DATE_FIELD, 30) AND isValid
    isValid = IsValidField(paymentRow, OrderData.NAME_ON_CARD_FIELD, 40) AND isValid
    isValid = IsValidField(paymentRow, OrderData.BILLING_ADDRESS_FIELD, 255) AND isValid

    '
    ' Validate the order items and recalculate the subtotal
    '
    Dim itemRows As DataRowCollection = order.Tables(OrderData.ORDER_ITEMS_TABLE).Rows
    Dim itemRow As DataRow
    Dim subTotal as Decimal
    subTotal = New Decimal(0)
   
    For Each itemRow In itemRows
        itemRow.ClearErrors
        subTotal = subTotal.Add(subTotal, CType(itemRow(OrderData.EXTENDED_FIELD), Decimal))
       
        If CType(itemRow(OrderData.PRICE_FIELD), Decimal) <= 0 Then
            itemRow.SetColumnError(OrderData.PRICE_FIELD, OrderData.INVALID_FIELD)
            isValid = False
        End If
        If (CType(itemRow(OrderData.QUANTITY_FIELD), Short) <= 0) Then
            itemRow.SetColumnError(OrderData.QUANTITY_FIELD, OrderData.INVALID_FIELD)
            isValid = False
        End If
    Next
                         
    '
    ' Verify the subtotal
    '
    If subTotal <> CType(summaryRow(OrderData.SUB_TOTAL_FIELD), Decimal) Then
        summaryRow.SetColumnError(OrderData.SUB_TOTAL_FIELD, OrderData.INVALID_FIELD)
        isValid = False
    End If
                         
    If isValid Then
        With New dataAccess.Orders
            isValid = .InsertOrderDetail(order) > 0
        End With
    End IF

    InsertOrder = isValid
End Function
数据访问源代码
Duwamish7.DataAccess.Orders.InsertOrderDetail 方法源代码的默认位置是 [安装 Visual Studio .NET 的驱动器号]:/Program Files/Microsoft Visual Studio .NET 2003/Enterprise Samples/Duwamish CS/DataAccess/Orders.cs 文件。
注意   如果安装了 Visual Basic .NET 版本,则 Duwamish 7.0 VB 将替换路径中的 Duwamish 7.0 CS,其文件名相同,但扩展名是 vb 而不是 cs。
Duwamish7.DataAccess.Orders.InsertOrderDetail 方法:
[C#]
/// <summary>
///     Inserts an Order into the database.
///     <param name="order">
///         An OrderData object containing the necessary order information.
///     </param>
///     <retvalue>OrderId:  The id of the newly added order.</retvalue>
/// </summary>
public int InsertOrderDetail(OrderData order)
{
    if ( insertCommand == null )
    {
        throw new System.ObjectDisposedException( GetType().FullName );
    }           
   
    DataTable      table;
    DataRowCollection rows;
    DataRow        row;
    DateTime       saleDate;
    //
    // Create a new row for the order itself (the detail rows already exist)
    //
    table = order.Tables[OrderData.ORDER_TABLE];
    //
    // Get the rows collection, clear it and add the new row
    //
    rows = table.Rows;
   
    rows.Clear();
   
    row = table.NewRow();
   
    row.BeginEdit();
    row[OrderData.CUSTOMER_ID_FIELD] = order.Tables[OrderData.CUSTOMER_TABLE].Rows[0][OrderData.PKID_FIELD];
    row.EndEdit();
   
    rows.Add(row);
    //
    // Order Line Details are passed as comma separated lists of Items, Quantities and Prices
    //
    StringBuilder itemList     = new StringBuilder();
    StringBuilder quantityList = new StringBuilder();
    StringBuilder priceList    = new StringBuilder();
   
    table = order.Tables[OrderData.ORDER_ITEMS_TABLE];
    rows  = table.Rows;
    //
    // Create the string lists
    //
    for ( int i = 0; i < rows.Count; i++ )
    {
        row = rows[i];
       
        itemList.Append(row[OrderData.ITEM_NUMBER_FIELD]).Append(',');
        quantityList.Append(row[OrderData.QUANTITY_FIELD]).Append(',');
        priceList.Append(row[OrderData.PRICE_FIELD]).Append(',');
    }
   
    if ( rows.Count != 0 )
    {
        //
        // Remove trailing comma
        //
        itemList.Remove(itemList.Length - 1, 1);
        quantityList.Remove(quantityList.Length - 1, 1);
        priceList.Remove(priceList.Length - 1, 1);
    }

    saleDate = DateTime.Now;
    //
    // Build the parameters for the command
    //
    SqlParameterCollection sqlParams  = insertCommand.Parameters;
    //
    // Customer Information
    //
    sqlParams["@CustomerId"].Value = order.Tables[OrderData.CUSTOMER_TABLE].Rows[0][OrderData.PKID_FIELD].ToString();
    //
    // Shipping Information
    //
    row = order.Tables[OrderData.SHIPPING_ADDRESS_TABLE].Rows[0];
   
    sqlParams["@ShipToName"].Value  = row[OrderData.SHIP_TO_NAME_FIELD].ToString();
    sqlParams["@Address"].Value     = row[OrderData.ADDRESS_FIELD].ToString();
    sqlParams["@Country"].Value     = row[OrderData.COUNTRY_FIELD].ToString();
    sqlParams["@PhoneNumber"].Value = row[OrderData.PHONE_NUMBER_FIELD].ToString();
    sqlParams["@Fax"].Value         = row[OrderData.FAX_FIELD].ToString();
    //
    // Summary Information
    //
    row = order.Tables[OrderData.ORDER_SUMMARY_TABLE].Rows[0];
   
    sqlParams["@ShippingHandling"].Value = row[OrderData.SHIPPING_HANDLING_FIELD].ToString();
    sqlParams["@SubTotal"].Value         = row[OrderData.SUB_TOTAL_FIELD].ToString();
    sqlParams["@Tax"].Value              = row[OrderData.TAX_FIELD].ToString();
    //
    // Payment Information
    //
    row = order.Tables[OrderData.PAYMENT_TABLE].Rows[0];
   
    sqlParams["@CreditCardNumber"].Value = row[OrderData.CREDIT_CARD_NUMBER_FIELD].ToString();
    sqlParams["@ExpirationDate"].Value   = row[OrderData.EXPIRATION_DATE_FIELD].ToString();
    sqlParams["@NameOnCard"].Value       = row[OrderData.NAME_ON_CARD_FIELD].ToString();
    sqlParams["@CreditCardType"].Value   = row[OrderData.CREDIT_CARD_TYPE_FIELD].ToString();
    //
    // order and Line Items
    //
    sqlParams["@Status"].Value       = 0;
    sqlParams["@OrderDate"].Value    = saleDate;
    sqlParams["@ItemIdList"].Value   = itemList.ToString();
    sqlParams["@QuantityList"].Value = quantityList.ToString();
    sqlParams["@PriceList"].Value    = priceList.ToString();
    //
    // Open must be called on the active connection when execute is called.
    //
    if ( insertCommand.Connection.State != ConnectionState.Open )
        insertCommand.Connection.Open();
    //
    // Execute the insert
    //       
    insertCommand.ExecuteNonQuery();
    //
    // Retrieve the out parameters from the stored procedure call
    // and store them back into the original dataset.
    //
    row = order.Tables[OrderData.ORDER_TABLE].Rows[0];
   
    row.BeginEdit();
    row[OrderData.DATE_FIELD]    = String.Format("{0:d}", saleDate);
    row[OrderData.SALE_ID_FIELD] = sqlParams["@PKId"].Value;
    row.EndEdit();
   
    order.AcceptChanges();

    return (int)(sqlParams["@PKId"].Value);
}
[Visual Basic .NET]
'----------------------------------------------------------------
' Function InsertOrderDetail:
'   Retrieves a book for a specified book id.
' Returns:
'   OrderId:  The id of the newly added order.
' Parameters:
'   [in]  Order: an OrderData object containing the necessary
'               order information.
'----------------------------------------------------------------
Public Function InsertOrderDetail(ByVal order As OrderData) As Integer
    Dim table       As DataTable
    Dim row         As DataRow
    Dim saleDate    As DateTime
    Dim i           As Integer
    '
    ' Create a new row for the order itself (the detail rows already exist)
    '
    With order.Tables(OrderData.ORDER_TABLE)
        .Rows.Clear
        row = .NewRow
        row.BeginEdit
        row.Item(OrderData.CUSTOMER_ID_FIELD) = order.Tables(OrderData.CUSTOMER_TABLE).Rows(0).Item(OrderData.PKID_FIELD)
        row.EndEdit
        .Rows.Add(row)
    End With
    '
    ' Order Line Details are passed as comma separated lists of Items, Quantities and Prices
    '
    Dim itemList As New StringBuilder
    Dim quantityList As New StringBuilder
    Dim priceList As New StringBuilder

    With order.Tables(OrderData.ORDER_ITEMS_TABLE)
        For i = 0 To .Rows.Count - 1
            itemList.Append(.Rows(i).Item(OrderData.ITEM_NUMBER_FIELD)).Append(",")
            quantityList.Append(.Rows(i).Item(OrderData.QUANTITY_FIELD)).Append(",")
            priceList.Append(.Rows(i).Item(OrderData.PRICE_FIELD)).Append(",")
        Next
       
        If .Rows.Count <> 0 Then
            '
            ' Remove trailing comma
            '
            itemList.Remove(itemList.Length - 1, 1)
            quantityList.Remove(quantityList.Length - 1, 1)
            priceList.Remove(priceList.Length - 1, 1)
        End If
    End With

    saleDate = DateTime.Now
    '
    ' Build the parameters for the command
    '
    Dim Command As SQLCommand = GetInsertCommand
   
    With Command.Parameters
        '
        ' Customer Information
        '
        .Item("@CustomerId").Value = order.Tables(OrderData.CUSTOMER_TABLE).Rows(0).Item(OrderData.PKID_FIELD)
        '
        ' Shipping Information
        '
        table = order.Tables(OrderData.SHIPPING_ADDRESS_TABLE)
       
        .Item("@ShipToName").Value = CStr(table.Rows(0).Item(OrderData.SHIP_TO_NAME_FIELD))
        .Item("@Address").Value = CStr(table.Rows(0).Item(OrderData.ADDRESS_FIELD))
        .Item("@Country").Value = CStr(table.Rows(0).Item(OrderData.COUNTRY_FIELD))
        .Item("@PhoneNumber").Value = CStr(table.Rows(0).Item(OrderData.PHONE_NUMBER_FIELD))
        .Item("@Fax").Value = CStr(table.Rows(0).Item(OrderData.FAX_FIELD))
        '
        ' Summary Information
        '
        table = order.Tables(OrderData.ORDER_SUMMARY_TABLE)
       
        .Item("@SubTotal").Value = table.Rows(0).Item(OrderData.SUB_TOTAL_FIELD).ToString
        .Item("@Tax").Value = table.Rows(0).Item(OrderData.TAX_FIELD).ToString
        .Item("@ShippingHandling").Value = table.Rows(0).Item(OrderData.SHIPPING_HANDLING_FIELD).ToString
        '
        ' Payment Information
        '
        table = order.Tables(OrderData.PAYMENT_TABLE)
       
        .Item("@CreditCardNumber").Value = CStr(table.Rows(0).Item(OrderData.CREDIT_CARD_NUMBER_FIELD))
        .Item("@ExpirationDate").Value = CStr(table.Rows(0).Item(OrderData.EXPIRATION_DATE_FIELD))
        .Item("@NameOnCard").Value = CStr(table.Rows(0).Item(OrderData.NAME_ON_CARD_FIELD))
        .Item("@CreditCardType").Value = CStr(table.Rows(0).Item(OrderData.CREDIT_CARD_TYPE_FIELD))
       
        .Item("@Status").Value = 0
        .Item("@OrderDate").Value = saleDate
        .Item("@ItemIdList").Value = itemList.ToString
        .Item("@QuantityList").Value = quantityList.ToString
        .Item("@PriceList").Value = priceList.ToString
    End With
    '
    ' open must be called on the active connection when execute is called.
    '
    With Command
        Try
            '
            ' Check if connection is already open
            '
            If (.Connection.State <> ConnectionState.Open) Then
                .Connection.Open
            End If
   
            '
            ' Execute the insert
            '
            .ExecuteNonQuery
        Finally
            If Not .Connection Is Nothing Then
                .Connection.Close()
                .Connection.Dispose()
            End If
            .Dispose()
        End Try
    End With
   
    '
    ' Retrieve the out parameters from the stored procedure call
    ' and store them back into the original dataset.
    '
    With order.Tables(OrderData.ORDER_TABLE).Rows(0)
        .BeginEdit
        'Date format appropriate for the Regional Settings
        .Item(OrderData.DATE_FIELD) = System.String.Format("{0:d}", saleDate)
        .Item(OrderData.SALE_ID_FIELD) = Command.Parameters("@PKId").Value
        .EndEdit
    End with

    order.AcceptChanges

    InsertOrderDetail = CInt(Command.Parameters("@PKId").Value)
End Function
SPROC
SQL 存储过程的默认位置是 [安装 Visual Studio .NET 的驱动器号]:/Program Files/Microsoft Visual Studio .NET 2003/Enterprise Samples/Duwamish 7.0 CS/Database/Sql/d7_sprocs.sql 文件。
注意   如果安装了 Visual Basic .NET 版本,则 Duwamish 7.0 VB 将替换路径中的 Duwamish 7.0 CS。
InsertSale SPROC:
--------------------------------------------------
-- InsertSale
--------------------------------------------------
CREATE PROCEDURE InsertSale
    @PKId               INT = NULL OUTPUT,
    @CustomerId         INT = NULL,
    @Status             INT = NULL,
    @OrderDate          DATETIME = NULL,
    @ShippingHandling   MONEY = NULL,
    @ShipToName         NVARCHAR(40) = NULL,
    @Address            NVARCHAR(255) = NULL,
    @Country            NVARCHAR(40) = NULL,
    @PhoneNumber        NVARCHAR(30) = NULL,
    @Fax                NVARCHAR(30) = NULL,
    @SubTotal           MONEY = NULL,
    @Tax                MONEY = NULL,
    @CreditCardType     NVARCHAR(40) = NULL,
    @CreditCardNumber   NVARCHAR(32) = NULL,
    @ExpirationDate     NVARCHAR(30) = NULL,
    @NameOnCard         NVARCHAR(40) = NULL,
    @ItemIdList         NVARCHAR(4000) = NULL,
    @QuantityList       NVARCHAR(4000) = NULL,
    @PriceList          NVARCHAR(4000) = NULL
AS
    SET NOCOUNT ON

    -- GET ADDRESS IDENTIFIER
    -- Retrieve Address reference into @AddressId
    DECLARE @ShipToAddressId INT

    SET XACT_ABORT ON

    BEGIN TRANSACTION
        -- Insert New Shipping Address
        -- Retrieve Shipping Address into @AddressId
        -- CustomerId is NULL for a shipping address
        EXEC InsertAddress @Address,
                           @Country,
                           @PhoneNumber,
                           @Fax,
                           NULL,
                           @ShipToAddressId OUTPUT

        INSERT Orders(CustomerId,
                      Status,
                      OrderDate,
                      ShippingHandling,
                      ShipToName,
                      ShipToAddressId,
                      SubTotal,
                      Tax,
                      CreditCardType,
                      CreditCardNumber,
                      ExpirationDate,
                      NameOnCard)

        SELECT @CustomerId,
               @Status,
               @OrderDate,
               @ShippingHandling,
               @ShipToName,
               @ShipToAddressId,
               @SubTotal,
               @Tax,
               @CreditCardType,
               @CreditCardNumber,
               @ExpirationDate,
               @NameOnCard


        --Get PKId from inserted Order
        SELECT @PKId = @@IDENTITY

        -- Insert Order Detail List
        IF @ItemIdList IS NOT NULL
            EXECUTE InsertOrderDetailsByList @PKId, @ItemIdList, @QuantityList, @PriceList

        -- return @PKId in resultset
        SELECT @PKId 'PKId'

    COMMIT TRANSACTION

    RETURN 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值