I have a create view for invoices that is failing on db.SaveChanges() on the HTTPPOST. The exception message is {“Invalid column name ‘UserDetail_UserId’.”}. In the POST controller it looks like the invoiceitem object I’m trying to add to my InvoiceItems table is populated correctly with the selected username from a dropdownlistfor that gets populated by usernames from my UserDetails table. “UserId” is the key column in the UserDetails table, but it’s not used in the dropdownlist so I’m unclear why any data is trying to be saved to a “UserDetail_UserId” column. My code below:
Models:
public class InvoiceItem
{
//Identity Column
public int ServiceID { get; set; }
[Key]
public string ProfileUserName { get; set; }
public DateTime InvoiceDate { get; set; }
public string Address { get; set; }
public string Note { get; set; }
public decimal Price { get; set; }
public decimal SubTotal { get; set; }
public bool InvoicePaid { get; set; }
}
public class UserDetail
{
[Key]
public Guid UserId { get; set; }
public string ProfileUserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Phone { get; set; }
public DateTime DateUpdated { get; set; }
public virtual ICollection<InvoiceItem> InvoiceItems { get; set; }
}
public class ProShotDB : DbContext
{
public DbSet<UserDetail> UserDetails { get; set; }
public DbSet<UserLinkToken> UserLinkTokens { get; set; }
public DbSet<InvoiceItem> InvoiceItems { get; set; }
}
Controllers:
public ActionResult Create()
{
ViewBag.ProfileUserNames = db.UserDetails.Select(
c => new
{
ProfileUserName = c.ProfileUserName,
NameAddress = c.FullName + " - " + c.Address
});
return View();
}
[HttpPost]
public ActionResult Create(InvoiceItem invoiceitem)
{
decimal Tax = 1.066m;
if (ModelState.IsValid)
{
invoiceitem.InvoiceDate = DateTime.Now;
invoiceitem.SubTotal = invoiceitem.Price*Tax;
invoiceitem.InvoicePaid = false;
db.InvoiceItems.Add(invoiceitem);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.ProfileUserNames = db.UserDetails.Select(
c => new
{
ProfileUserName = c.ProfileUserName,
NameAddress = c.FullName + " - " + c.Address
});
return View(invoiceitem);
}
View:
@model Pro_Shot_Portal.Models.InvoiceItem
@{
ViewBag.Title = "Input Invoice";
}
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Input Invoice:</legend>
<div class="alert alert-error" style="width:250px;">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>Warning!</strong> Assigning invoice to wrong user could cause major problems, please triple check before proceeding.
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ProfileUserName, "Attach invoice to user")
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.ProfileUserName, new SelectList(ViewBag.ProfileUserNames, "ProfileUserName", "NameAddress"), "-- Pick Client For Invoice --")
@Html.ValidationMessageFor(model => model.ProfileUserName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Address)
@Html.ValidationMessageFor(model => model.Address)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Note)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Note)
@Html.ValidationMessageFor(model => model.Note)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Price)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Price)
@Html.ValidationMessageFor(model => model.Price)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Cancel Invoice Creation", "Index")
</div>
From what I can tell the invoiceitem model object properties are filled with the proper data, and the only database change I’m invoking with db.SaveChanges() is “db.InvoiceItems.Add(invoiceitem);”. Can anyone tell me where and why it’s trying to access, write or update a column named “UserDetails_UserId”. Maybe I messed something up on the DropdownListFor since that’s the only part interacting with the UserDetails table?
Thanks.
You have a one-to-many relationship setup, the column name you are seeing with the underscores in the exception is the relationship default generated. See here for more details.