- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Connot save "copied" entity
Joined: 04-Jan-2007
Hi,
I have 2 windows-user-controls, one called order and one called car. The order control contains 10 car controls (displayed in tab view). A car control contains information like manufacturer, model, registration number aso. From the order control you can "copy" the content of one car control to other car controls, but when I try to save the order (containing the cars) it fails when it try to save the copied car, and I get the following error:
An exception was caught during the execution of an action query: Cannot insert the value NULL into column 'OrderID', table 'BiludanBTK.dbo.Car'; column does not allow nulls. INSERT fails.
The statement has been terminated.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception.
System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'OrderID', table 'BiludanBTK.dbo.Car'; column does not allow nulls. INSERT fails.
The statement has been terminated.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at SD.LLBLGen.Pro.ORMSupportClasses.ActionQuery.Execute()
I have debugged and the CarEntity that fails to be saved have an OrderID.
This is the code that copies the values:
private void but_copyCars_Click(object sender, EventArgs e)
{
CarCopyEntity carToCopy = ((Car)tab_cars.Controls.Find("uc_car" + (_carIndesToCopy + 1).ToString(), true)[0]).UnbindCarValuesForCarCopy();
for (int i = 1; i <= 10; i++)
{
CheckBox chkBox = (CheckBox)pan_copyCar.Controls.Find("chk_copyToCar" + i.ToString(), true)[0];
if ((chkBox.Enabled) && (chkBox.Checked))
{
((Car)tab_cars.Controls.Find("uc_car" + i.ToString(), true)[0]).BindCarValues(carToCopy);
}
}
UpdatePrices(sender, e);
pan_copyCar.Visible = false;
}
This Unbinds the values:
public CarCopyEntity UnbindCarValuesForCarCopy()
{
CarCopyEntity carCopy = new CarCopyEntity();
if ((com_carModel.Enabled) && (com_carModel.SelectedItem != null) && (((CarModelEntity)com_carModel.SelectedItem).CarModelID != Guid.Empty))
carCopy.CarModel = (CarModelEntity)com_carModel.SelectedItem;
else
carCopy.CarModel = null;
carCopy.RegMva = txt_regMva.Text;
if (chk_extraFeeLarge.Checked)
carCopy.CarTypeID = (int)CarType.Large;
else if (chk_extraFeeSmall.Checked)
carCopy.CarTypeID = (int)CarType.Small;
else
carCopy.CarTypeID = null;
carCopy.ExpressDelivery = chk_expressDelivery.Checked;
if (chk_difrentDestinationAddressOnInvoice.Checked)
carCopy.Address = ((ComboAddress)com_invoiceDestinationAddress.SelectedItem).Address;
else
carCopy.Address = null;
if ((com_FromAddress.SelectedItem != null) && (((ComboAddress)com_FromAddress.SelectedItem).Address.AddressID != Guid.Empty))
carCopy.PickupAddress = (ComboAddress)com_FromAddress.SelectedItem;
if ((com_ToAddress.SelectedItem != null) && (((ComboAddress)com_ToAddress.SelectedItem).Address.AddressID != Guid.Empty))
carCopy.DestinationAddress = (ComboAddress)com_ToAddress.SelectedItem;
if ((com_Reloading1.SelectedItem != null) && (((AddressEntity)com_Reloading1.SelectedItem).AddressID != Guid.Empty))
carCopy.Reloading1 = (AddressEntity)com_Reloading1.SelectedItem;
if ((com_Reloading2.SelectedItem != null) && (((AddressEntity)com_Reloading2.SelectedItem).AddressID != Guid.Empty))
carCopy.Reloading2 = (AddressEntity)com_Reloading2.SelectedItem;
carCopy.CommentPublic = txt_commentPublic.Text;
carCopy.CommentInternal = txt_commentInternal.Text;
return carCopy;
}
And this binds the values:
public void BindCarValues(CarCopyEntity car)
{
_disablePriceCalc = true;
if (car.CarModel.CarModelID != Guid.Empty)
{
com_carManufacturer.SelectedItem = car.CarModel.CarManufacturer;
com_carModel.SelectedItem = car.CarModel;
}
txt_regMva.Text = car.RegMva;
chk_extraFeeSmall.Checked = (car.CarTypeID == (int)CarType.Small);
chk_extraFeeLarge.Checked = (car.CarTypeID == (int)CarType.Large);
chk_expressDelivery.Checked = car.ExpressDelivery;
if ((car.InvoiceDestinationID.HasValue) && (car.InvoiceDestinationID.Value != Guid.Empty))
{
chk_difrentDestinationAddressOnInvoice.Checked = true;
com_invoiceDestinationAddress.SelectedItem = new ComboAddress(car.Address);
}
if ((car.PickupAddress != null) && (car.PickupAddress.Address.AddressID != Guid.Empty))
com_FromAddress.SelectedItem = car.PickupAddress;
if ((car.DestinationAddress != null) && (car.DestinationAddress.Address.AddressID != Guid.Empty))
com_ToAddress.SelectedItem = car.DestinationAddress;
if ((car.Reloading1 != null) && (car.Reloading1.AddressID != Guid.Empty))
com_Reloading1.SelectedItem = car.Reloading1;
if ((car.Reloading2 != null) && (car.Reloading2.AddressID != Guid.Empty))
com_Reloading2.SelectedItem = car.Reloading2;
txt_commentInternal.Text = car.CommentInternal;
txt_commentPublic.Text = car.CommentPublic;
UpdateDispatchList();
_disablePriceCalc = false;
}
If I add more cars manually there is no problem.
Where should I look to solve this?
I can't see where the OrderId of the copied car is being set.
All I see from the code posted is that you copy data from textboxes (controls) of one tab to those of another tab.
How do you save the Copied Car? Do you Add it to the Order.CarCollection afterwards so it takes the OrderId from this association?
Joined: 04-Jan-2007
Yes the cars are added to a collection. When I save this is called:
private void UnbindOrderValues()
{
if ((_order.IsNew) && (_order.OrderID == Guid.Empty))
_order.OrderID = Guid.NewGuid();
if (com_customer.SelectedItem != null)
_order.Customer = ((ComboCustomer)com_customer.SelectedItem).Customer;
else
_order.Customer = null;
if (rad_priceTypeNormal.Checked)
_order.PriceTypeID = (int)OrderPriceType.Normal;
else if (rad_priceTypeFixed.Checked)
{
_order.PriceTypeID = (int)OrderPriceType.Fixed;
decimal? orderPrice = BTK.Services.ParseHelper.ParseDecimal(txt_price.Text);
if (orderPrice.HasValue)
_order.Price = orderPrice.Value;
else
_order.Price = -1;
}
else if (rad_priceTypeFullLoad.Checked)
_order.PriceTypeID = (int)OrderPriceType.FullLoad;
else if (rad_priceTypeNordania.Checked)
_order.PriceTypeID = (int)OrderPriceType.Nordania;
_order.UseCustomerDiscount = chk_discount.Checked;
if (_order.PriceTypeID == (int)OrderPriceType.FullLoad)
{
_order.FullLoadPickupAreaDefinition = ((ComboArea)com_fullLoadPickupArea.SelectedItem).AreaDefinition;
_order.FullLoadDesternationAreaDefinition = ((ComboArea)com_fullLoadDestinationArea.SelectedItem).AreaDefinition;
}
else
{
_order.FullLoadPickupAreaDefinition = null;
_order.FullLoadDesternationAreaDefinition = null;
}
_order.CustomerRef = txt_customerRef.Text;
if ((com_commission.SelectedItem != null) && (((CommissionEntity)com_commission.SelectedItem).CommissionID != Guid.Empty))
_order.Commission = (CommissionEntity)com_commission.SelectedItem;
_order.Car.Items.Clear();
for (int i = 1; i <= 10; i++)
{
Car uc_car = (Car)tab_cars.Controls.Find("uc_car" + i.ToString(), true)[0];
CarEntity car = uc_car.UnbindCarValues();
if ((car.CarModel != null) && (car.CarModelID != Guid.Empty) && (CarService.CarHasPickupAndDestinationAddress(car)))
{
_order.Car.Items.Add(car);
car.Order = _order;
}
}
}
And where the cars are handled tis is called:
public CarEntity UnbindCarValues()
{
//Dispatches is handled while addresses and loadingareas is changed
if (_car.IsNew)
_car.CarID = Guid.NewGuid();
if ((com_carModel.Enabled) && (com_carModel.SelectedItem != null) && (((CarModelEntity)com_carModel.SelectedItem).CarModelID != Guid.Empty))
_car.CarModel = (CarModelEntity)com_carModel.SelectedItem;
else
_car.CarModel = null;
_car.RegMva = txt_regMva.Text;
if (chk_extraFeeLarge.Checked)
_car.CarTypeID = (int)CarType.Large;
else if (chk_extraFeeSmall.Checked)
_car.CarTypeID = (int)CarType.Small;
else
_car.CarTypeID = null;
_car.ExpressDelivery = chk_expressDelivery.Checked;
if ((chk_difrentDestinationAddressOnInvoice.Checked)
&& (((ComboAddress)com_invoiceDestinationAddress.SelectedItem).Address != null)
&& (((ComboAddress)com_invoiceDestinationAddress.SelectedItem).Address.AddressID != Guid.Empty))
_car.Address = ((ComboAddress)com_invoiceDestinationAddress.SelectedItem).Address;
else
_car.Address = null;
_car.CommentPublic = txt_commentPublic.Text;
_car.CommentInternal = txt_commentInternal.Text;
return _car;
}
Joined: 04-Jan-2007
The Button click event:
private void but_saveOrder_Click(object sender, EventArgs e)
{
if (ValidateOrder())
{
try
{
_order = OrderService.SaveOrder(_order);
}
catch (UnableToDeleteDispatchException)
{
MessageBox.Show("Der skedte en fejl, og ordren kunne ikke gemmes.\n Har du forsøgt at fjerne en bil med afsluttede kørsler?", "Fejl", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\n" + ex.InnerException + "\n" + ex.InnerException.InnerException, "Fejl", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
}
And the Save method
public static OrderEntity SaveOrder(OrderEntity orderToSave)
{
if (!orderToSave.IsNew)
{
OrderEntity currentOrder = GetOrder(orderToSave.OrderID);
foreach (CarEntity car in currentOrder.Car)
{
if (!IsCarInOrder(orderToSave, car))
CarService.DeleteCar(car);
}
foreach (CarEntity car in orderToSave.Car)
{
CarService.SaveCar(car);
}
}
orderToSave.Save(true);
return GetOrder(orderToSave.OrderID);
}
What's the purpose of this loop: foreach (CarEntity car in orderToSave.Car) { CarService.SaveCar(car); }
Cars should be saved when you save the order, since you are passing true for recursive save. Please comment the above for loop and try again. Thanks.
Joined: 04-Jan-2007
I forgot the SaveCar, here it is:
public static void SaveCar(CarEntity carToSave)
{
if (carToSave.IsNew)
carToSave.Save(true);
else
{
CarEntity currentCar = new CarEntity(carToSave.CarID);
foreach (CarProductEntity cpe in currentCar.CarProduct)
{
if (!IsProductAssociatedToCar(cpe, carToSave))
{
CarEntity car = new CarEntity(cpe.Car.CarID);
ProductEntity product = new ProductEntity(cpe.Product.ProductID);
car.CarProduct.Remove(cpe);
product.CarProduct.Remove(cpe);
cpe.Delete();
}
}
foreach (DispatchEntity de in currentCar.Dispatch)
{
if ((!IsDispatchAssociatedToCar(de, carToSave)) && (!de.CompletedDate.HasValue))
{
if (de.DispatchListID.HasValue)
{
DispatchListEntity dispatchList = new DispatchListEntity(de.DispatchListID.Value);
dispatchList.Dispatch.Remove(de);
}
CarEntity car = new CarEntity(currentCar.CarID);
car.Dispatch.Remove(de);
de.Delete();
}
}
}
}
Joined: 04-Jan-2007
I found and solved the problem. In UnbindCarValuesForCarCopy() line 5 should be "carCopy.CarModel = new CarModelEntity(((CarModelEntity)com_carModel.SelectedItem).CarModelID);"
This way it's not a reference to (CarModelEntity)com_carModel.SelectedItem of the car we are copying from.