用户登录后,“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