arikve

Hello

Is it possible to copy items from one commerce site database to another commerce site database

i'm getting this error

Microsoft.CommerceServer.Runtime.CommerceException: LoadOrder Failed. ---> System.Runtime.InteropServices.COMException (0x80028019): DBStorage failed to load marshall field. The marshall field may be corrupted.
at Microsoft.CommerceServer.Interop.Orders.DBStorageClass.GetData(Object vtReserved, Object vtKey)
at Microsoft.CommerceServer.Interop.Orders.OrderGroupFreeThreaded.MyLoad(String& ordergroup_id, Object& MyLoadType)
at Microsoft.CommerceServer.Interop.Orders.OrderGroupFreeThreaded.LoadOrder(String strOrderGroupID)
--- End of inner exception stack trace ---
at Microsoft.CommerceServer.Internal.Common.Util.ThrowCommerceException(String message, Exception inner, String source)
at Microsoft.CommerceServer.Interop.Orders.OrderGroupFreeThreaded.LoadOrder(String strOrderGroupID)
at Microsoft.CommerceServer.Runtime.Orders.PurchaseOrder..ctor(Guid userID, Guid orderID, OrderContext orderContext)
at Microsoft.CommerceServer.Runtime.Orders.OrderContext.GetPurchaseOrder(Guid userID, Guid orderID)

Exception Message
LoadOrder Failed.

Exception InnerException
System.Runtime.InteropServices.COMException (0x80028019): DBStorage failed to load marshall field. The marshall field may be corrupted.
at Microsoft.CommerceServer.Interop.Orders.DBStorageClass.GetData(Object vtReserved, Object vtKey)
at Microsoft.CommerceServer.Interop.Orders.OrderGroupFreeThreaded.MyLoad(String& ordergroup_id, Object& MyLoadType)
at Microsoft.CommerceServer.Interop.Orders.OrderGroupFreeThreaded.LoadOrder(String strOrderGroupID)

Thanks

arik




Re: Commerce Server 2002 and Earlier DBStorage failed to load marshall field error

David Messner - MSFT

Hi Arik,

I put together a sample for you that should do this. Note that this uses private reflection to "trick" the OrderGroup into believing that it wasn't loaded from the database so that it will be persisted correctly on the destination database. That makes this fragile and it may not work with future service packs. I developed and tested this on CS2002 SP4.

**IMPORTANT**: Please back up your database before experimenting with this technique. I'd hate to see you lose data.

using System;
using System.Diagnostics;
using System.Data;
using System.Reflection;
using Microsoft.CommerceServer.Runtime;
using Microsoft.CommerceServer.Runtime.Diagnostics;
using Microsoft.CommerceServer.Runtime.Orders;
using Interop = Microsoft.CommerceServer.Interop.Orders;

// need references to:
// Microsoft.CommerceServer.Runtime.dll
// Microsoft.CommerceServer.Interop.Orders.Requisition.dll
// MSCSCoreLib.dll

namespace OrdersCopierSample
{

public class OrdersCopier
{
OrderContext sourceOrderSystem;
string sourceConnstr;
string destConnstr;

public OrdersCopier(string sourceConnstr, string destConnstr)
{
DebugContext debugContext = new ConsoleDebugContext(DebugMode.Debug);
sourceOrderSystem = new OrderContext(sourceConnstr, debugContext);
this.destConnstr = destConnstr;
this.sourceConnstr = sourceConnstr;
}

public void CopyOrders()
{
const int orderStatusNewOrder = 4;

// If you have a large number of orders, you will likely need to adapt
// this sample to use paging
OrderGroupSearch search = new OrderGroupSearch(sourceOrderSystem);
OrderGroupSearchOptions searchOptions = new OrderGroupSearchOptions();
search.OrderStatusFilter = orderStatusNewOrder;
DataSet ds = search.Search(searchOptions);

CopyOrders(ds);
}

private void CopyOrders(DataSet ds)
{
foreach (DataRow row in ds.Tables[0].Rows)
{
//foreach (DataColumn col in ds.Tables[0].Columns)
// Debug.WriteLine(string.Format("{0}={1}", col.ColumnName, row[col].ToString()));

CopyOrder((Guid)row["ordergroup_id"], (Guid)row["user_id"]);
}
}

private void CopyOrder(Guid purchaseOrderId, Guid userId)
{
Debug.WriteLine("Copying Order " + purchaseOrderId.ToString());
Interop.OrderGroupFreeThreaded orderGroup = new Interop.OrderGroupFreeThreaded();

// Load the Order from the source database
orderGroup.Initialize(this.sourceConnstr, userId.ToString(), null);
orderGroup.LoadOrder(purchaseOrderId.ToString());

// Re-initialize the Order with the destination connection string
orderGroup.Initialize(destConnstr, userId.ToString(), null);

// Trick the OrderGroup into thinking that it's a new Order
SetOrderGroupAsNew(orderGroup);

// And now save it to the new database
object trackingNumberObj = null;;
orderGroup.SaveAsOrder(ref trackingNumberObj);
}

private void SetOrderGroupAsNew(Interop.OrderGroupFreeThreaded orderGroup)
{
// WARNING: This requires Reflection permission and thus only works in full trust
// Furthermore, this is not guaranteed to work with future service packs of CS2002 (tested with SP4)
FieldInfo field = orderGroup.GetType().GetField("exists_in_database", BindingFlags.NonPublic | BindingFlags.Instance);
Int16 existsValue = 0;
field.SetValue(orderGroup, existsValue, 0, null, null);
}

}
}

regards
-David