【问题标题】:Issues with foreign keys when adding to database in MVC在 MVC 中添加到数据库时的外键问题
【发布时间】:2016-04-29 11:48:23
【问题描述】:

我有一个函数 (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>

类别数据库:

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

物品数据库:

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]));

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

【问题讨论】:

  • 检查 catID 作为主键存在于类别表中。
  • @Zaki 确实存在,在Category表中有名字“Id”,是主键。
  • 非常感谢@StephenMuecke

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


【解决方案1】:

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

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

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

另外,你需要修改你的POST方法,如果ModelState无效并且你返回视图,你需要重新赋值ViewBag.Id的值,否则会抛出异常

[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】:

    你有空的model.CategoryID

    @Html.ValidationMessageFor(model => model.CategoryID)
    

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

     ViewBag.Id = categories;
     return View();
    

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

    【讨论】:

      【解决方案3】:

      您发送 Vara 对象 CategoryID,因为 CategoryID 是 Category 表中的外键, 类别表已被您发送 CategoryID

      【讨论】:

      • 很难理解你在说什么,而且不够详细。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-05
      • 2022-07-29
      • 1970-01-01
      • 2016-02-01
      • 2011-10-07
      • 2014-01-14
      相关资源
      最近更新 更多