如何将自动生成的 ID 插入关联 table?
How do I insert autogenerated IDs into association table?
我正在尝试编写一个应用程序,从各种烹饪网站上抓取食谱和配料信息。它几乎按照我想要的方式工作,因为我可以成功地将食谱插入食谱 table 并将配料插入配料 table,但我无法填充关联 table.
我的大部分项目都遵循 this tutorial,但它没有演示如何插入关联 table。
我只为 Recipe 创建了一个控制器,其中 Create 函数接受您想要的食谱的 URL。我不想直接从 Ingredient table 操作数据,所以我没有为它创建控制器。
我创建了三个模型 类:食谱、成分和关联 table RecipeIngredient。 Recipe和RecipeIngredient是一对多的关系,Ingredient和RecipeIngredient是一对多的关系。
这些是我的模型:
public class Recipe
{
public int ID { get; set; }
public string Name { get; set; }
public string URL { get; set; }
public DateTime DateTimeCreated { get; set; }
public virtual ICollection<RecipeIngredient> RecipeIngredients { get; set; }
}
public class Ingredient
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime DateTimeCreated { get; set; }
public virtual ICollection<RecipeIngredient> RecipeIngredients { get; set; }
}
public class RecipeIngredient
{
public int ID { get; set; }
public int RecipeID { get; set; }
public int IngredientID { get; set; }
public DateTime DateTimeCreated { get; set; }
public virtual Recipe Recipe { get; set; }
public virtual Ingredient Ingredient { get; set; }
}
这是我的 DbContext:
public class RecipeListContext : DbContext
{
public RecipeListContext() : base("RecipeListContext")
{
}
public DbSet<Recipe> Recipes { get; set; }
public DbSet<RecipeIngredient> RecipeIngredients { get; set; }
public DbSet<Ingredient> Ingredients { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
这是来自我的控制器的相关代码:
public class RecipesController : Controller
{
private RecipeListContext db = new RecipeListContext();
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "URL")] Recipe recipe)
{
if (ModelState.IsValid)
{
Ingredient ingredient = new Ingredient();
RecipeIngredient recipeIngredient = new RecipeIngredient();
var htmlWeb = new HtmlWeb();
var document = htmlWeb.Load(recipe.URL);
//This is the route to the recipe and ingredients for
//allrecipes.com
var recipeName = document.DocumentNode.SelectNodes("//h1[@class='recipe-summary__h1']");
var ingredients = document.DocumentNode.SelectNodes("//span[@itemprop='ingredients']");
//I populate the Name and DateTimeCreated fields for Recipe here
recipe.Name = recipeName[0].InnerText;
recipe.DateTimeCreated = DateTime.Now;
db.Recipes.Add(recipe);
db.SaveChanges();
for (var i = 0; i < ingredients.Count; i++)
{
ingredient.Name = ingredients[i].InnerText;
ingredient.DateTimeCreated = DateTime.Now;
db.Ingredients.Add(ingredient);
db.SaveChanges();
//Here I tried to populate the RecipeIngredient object with
//the ID from the Ingredient object, but since that ID gets
//created in the database upon insertion, ingredient.ID is
//just null. I'm not sure how to access this ID in order to
//insert it into RecipeIngredient and I'm not even sure if
//this is the right (or best) approach to this problem.
//recipeIngredient.RecipeID = recipe.ID;
//recipeIngredient.IngredientID = ingredient.ID;
//db.RecipeIngredients.Add(recipeIngredient);
//db.SaveChanges();
}
return RedirectToAction("Index");
}
return View(recipe);
}
Entity Framework 中是否有一些功能允许我使用从插入到两个主要 table 中创建的自动生成的 ID 来填充关联 table?或者还有其他解决方案吗?
编辑:
三个问题阻止了我的应用程序按预期工作。
我需要取消注释将 ingredient.ID 和 recipe.ID 分配给 recipeIngredient 外键的代码。
我需要在 for 循环内实例化配方和成分对象,以便它们在 for 循环的每次传递开始时重新初始化。我在没有重新初始化它们的情况下收到参照完整性错误。
我需要填充 recipeIngredients 中的 DateTimeCreated 字段。我忘记这样做了,这导致数据库中出现数据类型不匹配错误,因为空值转换为 01/01/0001 或超出 DateTime 支持的日期范围的类似内容。
我认为 EF 应该使用以下身份更新您的实体对象:
试试这个
db.Recipes.Add(recipe);
db.SaveChanges();
int newPK = recipe.ID;
三个问题导致我的应用程序无法按预期工作。
我需要取消注释将 ingredient.ID 和 recipe.ID 分配给 recipeIngredient 外键的代码。
我需要在 for 循环内实例化配方和成分对象,以便它们在 for 循环的每次传递开始时重新初始化。我在没有重新初始化它们的情况下收到参照完整性错误。
填充 RecipeIngredients 中的 DateTimeCreated 字段,因为我之前忘记这样做了。
我更新后的工作代码如下:
public ActionResult Create([Bind(Include = "URL")] Recipe recipe)
{
if (ModelState.IsValid)
{
var htmlWeb = new HtmlWeb();
var document = htmlWeb.Load(recipe.URL);
var recipeName = document.DocumentNode.SelectNodes("//h1[@class='recipe-summary__h1']");
var ingredients = document.DocumentNode.SelectNodes("//span[@itemprop='ingredients']");
recipe.Name = recipeName[0].InnerText;
recipe.DateTimeCreated = DateTime.Now;
db.Recipes.Add(recipe);
db.SaveChanges();
for (var i = 0; i < ingredients.Count; i++)
{
//Moved these next two lines into the for loop
Ingredient ingredient = new Ingredient();
RecipeIngredient recipeIngredient = new RecipeIngredient();
ingredient.Name = ingredients[i].InnerText;
ingredient.DateTimeCreated = DateTime.Now;
db.Ingredients.Add(ingredient);
db.SaveChanges();
//uncommented this code
recipeIngredient.RecipeID = recipe.ID;
recipeIngredient.IngredientID = ingredient.ID;
//populated the DateTimeCreated field as I had forgotten
//to do so already
recipeIngredient.DateTimeCreated = DateTime.Now;
db.RecipeIngredients.Add(recipeIngredient);
db.SaveChanges();
}
return RedirectToAction("Index");
}
return View(recipe);
}
我正在尝试编写一个应用程序,从各种烹饪网站上抓取食谱和配料信息。它几乎按照我想要的方式工作,因为我可以成功地将食谱插入食谱 table 并将配料插入配料 table,但我无法填充关联 table.
我的大部分项目都遵循 this tutorial,但它没有演示如何插入关联 table。
我只为 Recipe 创建了一个控制器,其中 Create 函数接受您想要的食谱的 URL。我不想直接从 Ingredient table 操作数据,所以我没有为它创建控制器。
我创建了三个模型 类:食谱、成分和关联 table RecipeIngredient。 Recipe和RecipeIngredient是一对多的关系,Ingredient和RecipeIngredient是一对多的关系。
这些是我的模型:
public class Recipe
{
public int ID { get; set; }
public string Name { get; set; }
public string URL { get; set; }
public DateTime DateTimeCreated { get; set; }
public virtual ICollection<RecipeIngredient> RecipeIngredients { get; set; }
}
public class Ingredient
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime DateTimeCreated { get; set; }
public virtual ICollection<RecipeIngredient> RecipeIngredients { get; set; }
}
public class RecipeIngredient
{
public int ID { get; set; }
public int RecipeID { get; set; }
public int IngredientID { get; set; }
public DateTime DateTimeCreated { get; set; }
public virtual Recipe Recipe { get; set; }
public virtual Ingredient Ingredient { get; set; }
}
这是我的 DbContext:
public class RecipeListContext : DbContext
{
public RecipeListContext() : base("RecipeListContext")
{
}
public DbSet<Recipe> Recipes { get; set; }
public DbSet<RecipeIngredient> RecipeIngredients { get; set; }
public DbSet<Ingredient> Ingredients { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
这是来自我的控制器的相关代码:
public class RecipesController : Controller
{
private RecipeListContext db = new RecipeListContext();
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "URL")] Recipe recipe)
{
if (ModelState.IsValid)
{
Ingredient ingredient = new Ingredient();
RecipeIngredient recipeIngredient = new RecipeIngredient();
var htmlWeb = new HtmlWeb();
var document = htmlWeb.Load(recipe.URL);
//This is the route to the recipe and ingredients for
//allrecipes.com
var recipeName = document.DocumentNode.SelectNodes("//h1[@class='recipe-summary__h1']");
var ingredients = document.DocumentNode.SelectNodes("//span[@itemprop='ingredients']");
//I populate the Name and DateTimeCreated fields for Recipe here
recipe.Name = recipeName[0].InnerText;
recipe.DateTimeCreated = DateTime.Now;
db.Recipes.Add(recipe);
db.SaveChanges();
for (var i = 0; i < ingredients.Count; i++)
{
ingredient.Name = ingredients[i].InnerText;
ingredient.DateTimeCreated = DateTime.Now;
db.Ingredients.Add(ingredient);
db.SaveChanges();
//Here I tried to populate the RecipeIngredient object with
//the ID from the Ingredient object, but since that ID gets
//created in the database upon insertion, ingredient.ID is
//just null. I'm not sure how to access this ID in order to
//insert it into RecipeIngredient and I'm not even sure if
//this is the right (or best) approach to this problem.
//recipeIngredient.RecipeID = recipe.ID;
//recipeIngredient.IngredientID = ingredient.ID;
//db.RecipeIngredients.Add(recipeIngredient);
//db.SaveChanges();
}
return RedirectToAction("Index");
}
return View(recipe);
}
Entity Framework 中是否有一些功能允许我使用从插入到两个主要 table 中创建的自动生成的 ID 来填充关联 table?或者还有其他解决方案吗?
编辑: 三个问题阻止了我的应用程序按预期工作。
我需要取消注释将 ingredient.ID 和 recipe.ID 分配给 recipeIngredient 外键的代码。
我需要在 for 循环内实例化配方和成分对象,以便它们在 for 循环的每次传递开始时重新初始化。我在没有重新初始化它们的情况下收到参照完整性错误。
我需要填充 recipeIngredients 中的 DateTimeCreated 字段。我忘记这样做了,这导致数据库中出现数据类型不匹配错误,因为空值转换为 01/01/0001 或超出 DateTime 支持的日期范围的类似内容。
我认为 EF 应该使用以下身份更新您的实体对象:
试试这个
db.Recipes.Add(recipe);
db.SaveChanges();
int newPK = recipe.ID;
三个问题导致我的应用程序无法按预期工作。
我需要取消注释将 ingredient.ID 和 recipe.ID 分配给 recipeIngredient 外键的代码。
我需要在 for 循环内实例化配方和成分对象,以便它们在 for 循环的每次传递开始时重新初始化。我在没有重新初始化它们的情况下收到参照完整性错误。
填充 RecipeIngredients 中的 DateTimeCreated 字段,因为我之前忘记这样做了。
我更新后的工作代码如下:
public ActionResult Create([Bind(Include = "URL")] Recipe recipe)
{
if (ModelState.IsValid)
{
var htmlWeb = new HtmlWeb();
var document = htmlWeb.Load(recipe.URL);
var recipeName = document.DocumentNode.SelectNodes("//h1[@class='recipe-summary__h1']");
var ingredients = document.DocumentNode.SelectNodes("//span[@itemprop='ingredients']");
recipe.Name = recipeName[0].InnerText;
recipe.DateTimeCreated = DateTime.Now;
db.Recipes.Add(recipe);
db.SaveChanges();
for (var i = 0; i < ingredients.Count; i++)
{
//Moved these next two lines into the for loop
Ingredient ingredient = new Ingredient();
RecipeIngredient recipeIngredient = new RecipeIngredient();
ingredient.Name = ingredients[i].InnerText;
ingredient.DateTimeCreated = DateTime.Now;
db.Ingredients.Add(ingredient);
db.SaveChanges();
//uncommented this code
recipeIngredient.RecipeID = recipe.ID;
recipeIngredient.IngredientID = ingredient.ID;
//populated the DateTimeCreated field as I had forgotten
//to do so already
recipeIngredient.DateTimeCreated = DateTime.Now;
db.RecipeIngredients.Add(recipeIngredient);
db.SaveChanges();
}
return RedirectToAction("Index");
}
return View(recipe);
}