【问题标题】:Seeding data in Configuration.cs, creating duplicate data with AddOrUpdate在 Configuration.cs 中播种数据,使用 AddOrUpdate 创建重复数据
【发布时间】:2013-05-17 11:57:59
【问题描述】:

我在 Visual Studio 2012 Express 和 SQL Server 2012 Express 的 MVC 4 EF5 应用程序中使用迁移,使用 Code First。

我在configuration.cs中使用了Seed方法,首先创建了一个Tags表。当我从包管理器执行'Update-Database -verbose -force'时,它可以正常工作并且不会创建重复的标签 - 如果删除,则会重新创建它们:

db.Tags.AddOrUpdate(
   t => t.Name,
   new Tag { Name = "Bakery", NamePlural = "Bakeries" },
   new Tag { Name = "Bar", NamePlural = "Bars" },
   new Tag { Name = "Bookshop", NamePlural = "Bookshops" }
);

db.SaveChanges();

然后我尝试添加相关的地方数据:

db.Places.AddOrUpdate(
p => p.Name,
new Place
{
  Name = "Shoreditch Grind",
  URL = "shoreditch-grind-cafe",
  Address = "213 Old St",
  City = "London",
  PostCode = "EC1V 9NR",
  Website = "www.shoreditchgrind.com",
  Phone = "020 7490 0101",
  About = "Good coffee on the Silicon Roundabout",
  Image = "noimage.png",
  Tag = db.Tags.Single(t => t.Name == "Bar")
},

new Place
{
  Name = "The Old Blue Last",
  URL = "old-blue-last-pub",
  Address = "38 Great Eastern St",
  City = "London",
  PostCode = "EC2A 3ES",
  Website = "www.theoldbluelast.com",
  Phone = "020 7739 7033",
  About = "Pub of Vice Magazine",
  Image = "noimage.png",
  Tag = db.Tags.Single(t => t.Name == "Bakery")
}
);

然而,这会产生重复,每次我执行“Update-Database -verbose -force”时都会再次添加所有位置

我是 MVC 的新手 - 我也不完全理解它的作用:

p => p.Name,

我有一种感觉,也许我应该为每个对象手动添加 ID 值?

如何在不创建重复的 Places 的情况下运行它?

能够简单地将每个 Tag.Name 标记为唯一也很有用。

谢谢。

【问题讨论】:

  • 每次运行update-database 时都会调用Seed() 方法,我认为这就是为什么会出现重复项。如果您实际查看您的表 - 我怀疑可能有重复的 Places 行,但这些重复行(显然)会有不同的主键?
  • 是的,他们有不同的主键(PlaceID)。但是,它不会在标签表中创建重复项。修复它的最佳方法是什么?谢谢

标签: c# asp.net-mvc entity-framework asp.net-mvc-4 ef-code-first


【解决方案1】:

这可能有效:

var place = new Place
{
  Name = "The Old Blue Last",
  URL = "old-blue-last-pub",
  Address = "38 Great Eastern St",
  City = "London",
  PostCode = "EC2A 3ES",
  Website = "www.theoldbluelast.com",
  Phone = "123 456 789",  // updated number
  About = "Pub of Vice Magazine",
  Image = "noimage.png",
  TagID = db.Tags.Single(t => t.Name == "Bakery").TagID
};
db.Places.AddOrUpdate(p => p.Name, place);
db.SaveChanges();

由于“The Old Blue Last”已经存在,并且我们已经根据p.Name 进行了更新,它应该只更新将电话更改为“123 456 789”的条目。这与您尝试过的类似,但可能会奏效。查看更多here

你还提到你不确定p => p.Name 做了什么。 => 称为 Lambda 表达式。它是一个匿名函数。它是一个没有声明、访问修饰符、返回类型、名称等的方法。它是一个简写表达式,允许您在要使用它的地方编写方法。

查看更多 herehere.

【讨论】:

  • 感谢 p => p.Name 的解释。我现在 90% 在那里 - 它在上面的 AddOrUpdate 表达式中为你做了什么 - 为什么你需要调用匿名函数? (现在测试其他代码)
  • AddOrUpdate 采用键/值对。就您而言,关键是p => p.Name。 EF 获取此密钥(这将是您尝试插入的位置的名称)并根据数据库检查它以查看是否有任何记录与之匹配。在您的情况下,该值是您尝试插入的新“位置”。如果数据库中没有匹配项,则插入一条新记录。如果有,记录将被更新。在这种情况下使用 lambda 可以让您通过简写方式访问 Place 的属性。
  • 谢谢。那么为什么不能只输入属性“Place”而不是 Lambda 呢?
  • 上面的代码示例在空表的第一个“Update-Database -verbose -force”上运行良好。在第二次运行时失败:“更新条目时发生错误。有关详细信息,请参阅内部异常。”
  • 好的,我解决了 - 超级简单 - 感谢您帮助我到达那里... TagID = db.Tags.Single(t => t.Name == "Bakery").TagID
猜你喜欢
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-01
  • 2021-04-16
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多