[英]Error - The INSERT statement conflicted with the FOREIGN KEY constraint
使用EF Code First遷移時,在數據庫中用代碼創建項目時出現錯誤。
我已經檢查了與我的問題類似的關於stackoverflow的幾個QA,但是它們並不能幫助我解決問題。 我沒有使用自動遷移。
我按照本教程http://mahedee.net/cascading-dropdown-list-in-asp-net-mvc-a-sample-demonstration/#comment-17847創建了MainCategories / SubCategories的級聯下拉列表,並且在我的列表,但是當我創建一個項目時,出現以下錯誤:
INSERT語句與FOREIGN KEY約束“ FK_dbo.Fabrics_dbo.MainCategories_MainCategoryId”沖突。 數據庫“ MyFabricStashAppDb”的表“ dbo.MainCategories”的列“ MainCategoryId”中發生了沖突。 該語句已終止。
我的模型如下:My MainCategory.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MyFabricStashApp.Models
{
public class MainCategory
{
public int MainCategoryId { get; set; }
public string Name { get; set; }
public List<SubCategory1> SubCategories1 { get; set; }
}
}
我的SubCategory1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;
namespace MyFabricStashApp.Models
{
public class SubCategory1
{
public int SubCategory1Id { get; set; }
public string Name { get; set; }
public int MainCategoryId { get; set; }
public virtual MainCategory MainCategory { get; set; }
}
}
我的Fabric.cs(項目類)
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;
namespace MyFabricStashApp.Models
{
public class Fabric
{
public int FabricId { get; set; } //Item Number
public int MainCategoryId { get; set; }
public virtual MainCategory MainCategory { get; set; }
public int SubCategory1Id { get; set; }
public virtual SubCategory1 SubCategory1 { get; set; }
public string Name { get; set; }
public string ImagePath { get; set; }
public string Location { get; set; }
public string Type { get; set; } //Knit, Woven, Voile, Interfacing, Denim, Suiting, etc.
public string Weight { get; set; }//Lightweight, Medium, Heavy
public string Content { get; set; }//Cotton, Polyester, Nylon, etc.
public string Design { get; set; }//Marvel Comics, Amy Butler, etc.
public string Brand { get; set; } //Springs Creative Products, Free Spirit, Robert Kaufman, etc.
public double Quantity { get; set; }//.25 yd, .50 yd, .75 yd, 1.0 yd, etc.
public int Width { get; set; }// in inches, ie. 44", 54", etc.
public string Source { get; set; }//Joann
public string Notes { get; set; }
public List<string> Tags { get; set; }
public int ItemsSold { get; set; }
public virtual ICollection<Purchase> Purchases { get; set; }
}
}
這是我的遷移課程“添加遷移FirstMigration”
namespace MyFabricStashApp.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class FirstMigration : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Fabrics",
c => new
{
FabricId = c.Int(nullable: false, identity: true),
MainCategoryId = c.Int(nullable: false),
SubCategory1Id = c.Int(nullable: false),
Name = c.String(),
ImagePath = c.String(),
Location = c.String(),
Type = c.String(),
Weight = c.String(),
Content = c.String(),
Design = c.String(),
Brand = c.String(),
Quantity = c.Double(nullable: false),
Width = c.Int(nullable: false),
Source = c.String(),
Notes = c.String(),
ItemsSold = c.Int(nullable: false),
})
.PrimaryKey(t => t.FabricId)
.ForeignKey("dbo.MainCategories", t => t.MainCategoryId, cascadeDelete: false)
.ForeignKey("dbo.SubCategory1", t => t.SubCategory1Id, cascadeDelete: false)
.Index(t => t.MainCategoryId)
.Index(t => t.SubCategory1Id);
CreateTable(
"dbo.MainCategories",
c => new
{
MainCategoryId = c.Int(nullable: false, identity: true),
Name = c.String(),
})
.PrimaryKey(t => t.MainCategoryId);
CreateTable(
"dbo.SubCategory1",
c => new
{
SubCategory1Id = c.Int(nullable: false, identity: true),
Name = c.String(),
MainCategoryId = c.Int(nullable: false),
})
.PrimaryKey(t => t.SubCategory1Id)
.ForeignKey("dbo.MainCategories", t => t.MainCategoryId, cascadeDelete: false)
.Index(t => t.MainCategoryId);
CreateTable(
"dbo.Purchases",
c => new
{
PurchaseId = c.Int(nullable: false, identity: true),
PurchaseDate = c.DateTime(nullable: false),
PurchaseQuantity = c.Int(nullable: false),
PurchasePrice = c.Double(nullable: false),
FabricId = c.Int(nullable: false),
})
.PrimaryKey(t => t.PurchaseId)
.ForeignKey("dbo.Fabrics", t => t.FabricId, cascadeDelete: false)
.Index(t => t.FabricId);
}
public override void Down()
{
DropForeignKey("dbo.Fabrics", "SubCategory1Id", "dbo.SubCategory1");
DropForeignKey("dbo.Purchases", "FabricId", "dbo.Fabrics");
DropForeignKey("dbo.Fabrics", "MainCategoryId", "dbo.MainCategories");
DropForeignKey("dbo.SubCategory1", "MainCategoryId", "dbo.MainCategories");
DropIndex("dbo.Purchases", new[] { "FabricId" });
DropIndex("dbo.SubCategory1", new[] { "MainCategoryId" });
DropIndex("dbo.Fabrics", new[] { "SubCategory1Id" });
DropIndex("dbo.Fabrics", new[] { "MainCategoryId" });
DropTable("dbo.Purchases");
DropTable("dbo.SubCategory1");
DropTable("dbo.MainCategories");
DropTable("dbo.Fabrics");
}
}
}
我的FabricListViewModel.cs-創建此文件的目的是使“視圖”訪問所有類中所需的所有屬性。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MyFabricStashApp.Models
{
public class FabricListViewModel
{
public int FabricId { get; set; } //Item Number
public int MainCategoryId { get; set; }
public string MainCategoryName { get; set; }
public int SubCategory1Id { get; set; }
public string SubCategory1Name { get; set; }
public string Name { get; set; }
public string ImagePath { get; set; }
public string Location { get; set; }
public string Type { get; set; } //Knit, Woven, Voile, Interfacing, Denim, Suiting, etc.
public string Weight { get; set; }//Lightweight, Medium, Heavy
public string Content { get; set; }//Cotton, Polyester, Nylon, etc.
public string Design { get; set; }//Marvel Comics, Amy Butler, etc.
public string Brand { get; set; } //Springs Creative Products, Free Spirit, Robert Kaufman, etc.
public double Quantity { get; set; }//.25 yd, .50 yd, .75 yd, 1.0 yd, etc.
public int Width { get; set; }// in inches, ie. 44", 54", etc.
public string Source { get; set; }//Joann
public string Notes { get; set; }
public int ItemsSold { get; set; }
public int PurchaseCount { get; set; }
}
}
在我的控制器FabricController中,您可以看到我在List中包含MainCategory和SubCategory1模型,因此我可以訪問它們的屬性。 為了簡潔起見,我包括了Index操作和POST Create操作。
public class FabricController : Controller
{
private MyFabricStashDb db = new MyFabricStashDb();
// GET: Fabric
public ActionResult Index(string searchTerm = null)
{
var model = db.Fabrics.Include(f => f.MainCategory).Include(f => f.SubCategory1)
.OrderByDescending(f => f.ItemsSold)
.Where(f => searchTerm == null || f.Name.StartsWith(searchTerm))
.Select(f => new FabricListViewModel
{
FabricId = f.FabricId,
Name = f.Name,
MainCategoryId = f.MainCategoryId,
MainCategoryName = f.MainCategory.Name,
SubCategory1Id = f.SubCategory1Id,
SubCategory1Name = f.SubCategory1.Name,
ImagePath = f.ImagePath,
Location = f.Location,
Type = f.Type,
Weight = f.Weight,
Content = f.Content,
Design = f.Design,
Brand = f.Brand,
Quantity = f.Quantity,
Width = f.Width,
Source = f.Source,
Notes = f.Notes,
ItemsSold = f.ItemsSold,
PurchaseCount = f.Purchases.Count()
});
return View(model);
}
// POST: Fabric/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "FabricId,MainCategory,SubCategory1,SubCategory2,Name,ImagePath,Location,Type,Weight,Content,Design,Brand,Quantity,Width,Source,Notes,ItemsSold")] Fabric fabric, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
var filename = Path.GetFileName(file.FileName);
string fabricId = fabric.FabricId.ToString();
string myfile = fabricId + "_" + filename;
var path = Path.Combine(Server.MapPath("~/images"), myfile);
fabric.ImagePath = myfile;
file.SaveAs(path);
db.Fabrics.Add(fabric);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(fabric);
}
我需要在POST Create方法中綁定MainCategory和SubCategory1類的屬性嗎? 難道這就是為什么INSERT語句失敗的原因? 在“ db.SaveChanges();”上失敗 POST Create操作方法中的一行。
當我注釋掉這些public virtual MainCategory MainCategory {get; set;}
public virtual MainCategory MainCategory {get; set;}
屬性,它可以工作,並且我可以創建一個新的Item,但是我無法在FabricController中包含這些類,因為該屬性在Fabric類中不存在,因此我無法訪問它們的屬性。
笨拙的問題,這是一種簡化數據的方法。 每個子類別都有唯一的ID。 要鏈接到主要類別,可以通過結構所屬的子類別進行選擇。 那給了我們
public class Fabric
{
public int FabricId { get; set; } //Item Number
// public int MainCategoryId { get; set; }
// public virtual MainCategory MainCategory { get; set; }
public int SubCategory1Id { get; set; }
public virtual SubCategory1 SubCategory1 { get; set; }
public string Name { get; set; }
public string ImagePath { get; set; }
public string Location { get; set; }
public string Type { get; set; } //Knit, Woven, Voile, Interfacing, Denim, Suiting, etc.
public string Weight { get; set; }//Lightweight, Medium, Heavy
public string Content { get; set; }//Cotton, Polyester, Nylon, etc.
public string Design { get; set; }//Marvel Comics, Amy Butler, etc.
public string Brand { get; set; } //Springs Creative Products, Free Spirit, Robert Kaufman, etc.
public double Quantity { get; set; }//.25 yd, .50 yd, .75 yd, 1.0 yd, etc.
public int Width { get; set; }// in inches, ie. 44", 54", etc.
public string Source { get; set; }//Joann
public string Notes { get; set; }
public List<string> Tags { get; set; }
public int ItemsSold { get; set; }
public virtual ICollection<Purchase> Purchases { get; set; }
}
只要您通過以下方式檢索Fabric
db.Fabrics.Include("SubCategory1").Include("SubCategory1.MainCategory").FirstOrDefault(p => p.FabricId == <something>);
您可以引用Fabric.SubCategory1.MainCategory.Name
使用MainCategory / SubCategory1填充下拉列表,並確保在創建時將SubCategory1鍵放入Fabric記錄中。 應該簡化你的生活。 您的下拉列表將綁定到MainCategory的臨時字段和SubCategory1.SubCategoryId的列表模型。 為了顯示,您將從Fabric.SubCategory1.MainCategory.MainCategoryId字段填充臨時字段。 嗯
我將解決方法發布到這里。 上面的@juharr和@ user1011627在評論中回答了該問題,但我想發布解決方案,以防有人遇到相同的問題。
我只是在POST Create操作方法的BIND語句中添加了“ MainCategoryId”和“ SubCategory1Id”屬性。 參見下文,在FabricController中:
// POST: Fabric/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "FabricId,MainCategory,MainCategoryId, SubCategory1Id,SubCategory1,SubCategory2,Name,ImagePath,Location,Type,Weight,Content,Design,Brand,Quantity,Width,Source,Notes,ItemsSold")] Fabric fabric, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
var filename = Path.GetFileName(file.FileName);
string fabricId = fabric.FabricId.ToString();
string myfile = fabricId + "_" + filename;
var path = Path.Combine(Server.MapPath("~/images"), myfile);
fabric.ImagePath = myfile;
file.SaveAs(path);
db.Fabrics.Add(fabric);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(fabric);
}
我敢肯定還有其他方法可以做到這一點,但這對我來說是使其與應用程序中其他代碼一起使用的最簡單,最快的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.