I have the following model: Item contains Product, Shipping, UserId (that created this product). "Item : Product" and "Item : Shipping" is "1:1" relationship). When I want to add new Product to the database the SqlException occures:
Cannot insert the value NULL into column 'ProductId', table 'C:\USERS\ALEKSEY\REPOS\WORKING-COPY\WEBSTORE\WEBSTORE\APP_DATA\WEBSTORE.MDF.dbo.Products'; column does not allow nulls. INSERT fails.
Everything was working before I changed the "Is Identity" property of the column "ProductId" from true to false, so it is no longer autogenerated. I did it cause I need to upload data from xml file (and keep the ID from that file in ProductId). Also I need the user's ability to add new products.
Here is the controller action method that creates new product, shipping and the corresponding item:
public ViewResult Create()
{
var productId = 0;
for (var i = 0; i < Int32.MaxValue; i++)
{
if (_productRepository.GetProduct(i) == null)
productId = i;
}
// the same code as above to get shippingId
var p = _productRepository.CreateProduct(productId, "", "", 0, "", "", "");
var s = _shippingRepository.CreateShipping(shippingId, 0, "");
var userId = (Guid)Membership.GetUser().ProviderUserKey;
var model = new StoreEditViewModel(_productRepository)
{
CurrentItem = _itemsRepository.CreateItem(p.ProductId, s.ShippingId, userId, DateTime.Now),
};
return View("Edit", model);
}
If I comment the line with product creation the same exception will occure with shipping.
Here is the ProductRepository method that uses Linq To SQL to create new product:
public Product CreateProduct(int productId, string name, /* other properties */)
{
var product = new Product
{
ProductId = productId,
Name = name,
// other properties
};
_dataContext.Products.InsertOnSubmit(product);
_dataContext.SubmitChanges(); // SqlException occures !
return product;
}
How could I fix this?
Edit 1: I also tried to insert integer instead of productId in CreateProduct(100, other stuff) method. Still get the SqlException:
Cannot insert the value NULL into column 'ProductId', table 'WebStore.dbo.Products'; column does not allow nulls. INSERT fails. The statement has been terminated.
Edit 2: It appeared that _dataContext didn't knew about the changed Columns' properties (as @devio supported). I just needed to update MyAppDataContext class.
The question is actually answered but I have another problem: Now when I invoke Create() method Product, Shipping and Item entries are added to the corresponding tables. Than Create() method returns "Edit" view where You can fill the actual data (at the moment when the new item is created it's empty).
Than the form in "Edit" view should be processed by Edit() action method:
[HttpPost]
public ActionResult Edit(StoreEditViewModel model, HttpPostedFileBase image)
{
var p = model.CurrentItem.Product;
var s = model.CurrentItem.Shipping;
if (ModelState.IsValid)
{
if (image != null)
{
var path = AppDomain.CurrentDomain.BaseDirectory +
ConfigurationManager.AppSettings["product-images-directory"];
var imageName = "prod-" + p.ProductId.ToString(CultureInfo.InvariantCulture) + ".jpg";
image.SaveAs(path + imageName);
}
_productRepository.UpdateProduct(p);
_shippingRepository.UpdateShipping(s);
return RedirectToAction("Content");
}
return View("Edit", model);
}
And I get (my own translation) "Server Error in the application", stack trace:
[MissingMethodException: No parameterless constructor defined for this object.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +113
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
System.Activator.CreateInstance(Type type) +6
System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +183
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +564
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +411
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +317
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +117
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +324
System.Web.Mvc.Controller.ExecuteCore() +106
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +91
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +34
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +19
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +10
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +48
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9629708
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
I really don't know what to do with this strange stack trace, can't find any friendly line.
What could be the reason?