在MVC中添加到数据库时出现外键问题

时间:2016-04-29 11:48:24

标签: c# asp.net asp.net-mvc linq wcf

我有一个函数(addItem),它被添加到我的数据库中添加一个新行。但是当函数运行时,它会给我这个错误:

{"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK1\". The conflict occurred in database \"C:\\USERS\\ALAL0006\\DOWNLOADS\\SOA PROJEKT\\SOA PROJEKT\\SOA PROJEKT\\APP_DATA\\DATABASE1.MDF\", table \"dbo.Category\", column 'Id'.\r\nThe statement has been terminated."}

控制器:

public ActionResult Create()
    {
        IEnumerable<SelectListItem> categories = tbl.Category.Select(c => new SelectListItem
        {
            Value = SqlFunctions.StringConvert((double)c.Id).Trim(),
            Text = c.Namn
        });
        //ViewBag.Category = new SelectList(tbl.Category, "Id", "Namn");
        ViewBag.Id = categories;
        return View();
    }
    [HttpPost]
    public ActionResult Create(Vara newItm)
    {
        if (ModelState.IsValid)
        {
            srvc.addItem(newItm.Namn, newItm.Pris, newItm.CategoryID);
            return RedirectToAction("Create");
        }
        else
        {
            return View();
        }
    }

服务:

public void addItem(string name, int price, int ctgID)
    {
        Database1Entities1 tbl = new Database1Entities1();
        Vara newItm = new Vara() {

            Namn = name,
            Pris = price,
            CategoryID = ctgID,

        };
        tbl.Vara.Add(newItm);
        try
        {
            tbl.SaveChanges();
        }

cshtml文件:

        <div class="form-group">
        @Html.LabelFor(model => model.Namn, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Namn)
            @Html.ValidationMessageFor(model => model.Namn)
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Pris, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Pris)
            @Html.ValidationMessageFor(model => model.Pris)
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.CategoryID, "CategoryID", new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("Id", "Välj kategori")
            @Html.ValidationMessageFor(model => model.CategoryID)
        </div>
    </div>

类别DB:

CREATE TABLE [dbo].[Category] (
[Id]   INT           IDENTITY (1, 1) NOT NULL,
[Namn] VARCHAR (MAX) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC));

项目DB:

CREATE TABLE [dbo].[Vara] (
[Id]         INT           IDENTITY (1, 1) NOT NULL,
[Namn]       VARCHAR (MAX) NOT NULL,
[Pris]       INT           NOT NULL,
[CategoryID] INT           NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK1] FOREIGN KEY ([CategoryID]) REFERENCES [dbo].[Category] ([Id]));

我不确定我应该做些什么来解决这个问题。有什么想法吗?

3 个答案:

答案 0 :(得分:0)

中有空的model.CategoryID
@Html.ValidationMessageFor(model => model.CategoryID)

因为您已将类别列表存储到ViewBag.Id并显示带有空模型的视图:

 ViewBag.Id = categories;
 return View();

您的帖子是使用ctgID = 0生成的(默认值为整数)。 在通过EntityFramework保存到数据库的步骤中,您的插入可能会失败,因为您的Category表没有Id = 0的行。(MSSQL中的默认第一行Id为1)

答案 1 :(得分:0)

您的问题是,在POST方法中,newItm.CategoryID的值为0int的默认值),因为您从未为属性CategoryID生成表单控件(您生成的<select>元素用于属性Id)。

您需要将视图中的代码更改为(始终使用强类型xxxFor()方法)

@Html.DropDownListFor(m => m.CategoryID, (IEnumerable<SelectListItem>)ViewBag.Id, "Välj kategori")

此外,如果ViewBag.Id无效并且您返回视图,则需要修改POST方法以重新分配ModelState的值,否则将抛出异常

[HttpPost]
public ActionResult Create(Vara newItm)
{
    if (ModelState.IsValid)
    {
        ....
    }
    ViewBag.Id = ... // same code as used in the GET method.
    return View(newItm);
}

然而,更好的方法是使用视图模型(参考What is ViewModel in MVC?)。

public class VaraVM
{
    public int? ID { get; set; }
    ....
    [Display(Name = "Category")]
    [Required(ErrorMessage = "Please select a category")]
    public int SelectedCategory { get; set; }
    public IEnumerable<SelectistItem> CategoryList { get; set; }   
}

并在视图中

@Html.DropDownListFor(m => m.SelectedCategory , Model.CategoryList, "Välj kategori")

并在控制器中

public ActionResult Create()
{
    VaraVM model = new VaraVM();
    ConfigureViewModel(model);
    return View(model);
}

[HttpPost]
public ActionResult Create(VaraVM model)
{
    if (!ModelState.IsValid)
    {
        ConfigureViewModel(model);
        return View(model);  
    }
    // map the view model to a new instance of the data model
    // save and redirect
}

private void ConfigureViewModel(VaraVM model)
{
    model.CategoryList = .... // your query
}

答案 2 :(得分:-1)

你发送Vara对象的CategoryID,因为CategoryID中的CategoryID外键, 类别表已经发送CategoryID