C# 使用实体框架CF迁移添加记录
我的表a和表B具有以下关系: 表AC# 使用实体框架CF迁移添加记录,c#,.net,entity-framework,entity-framework-migrations,C#,.net,Entity Framework,Entity Framework Migrations,我的表a和表B具有以下关系: 表A Id ... 表B Id TableA_Id (foreign key table A) 我首先使用实体框架代码并激活了迁移 我想做的是进行迁移,在表a中为表B的每个现有记录添加一条记录,然后在表B中的新表a行中添加一个外键引用。 我使用了以下命令并创建了一个空迁移: Add-Migration <NameOfMyMigration> 在阅读了Alexander Derck的问题评论后,我得出了以下解决方案。我会把它贴在这里,以防其他人需
Id
...
表B
Id
TableA_Id (foreign key table A)
我首先使用实体框架代码并激活了迁移
我想做的是进行迁移,在表a中为表B的每个现有记录添加一条记录,然后在表B中的新表a行中添加一个外键引用。
我使用了以下命令并创建了一个空迁移:
Add-Migration <NameOfMyMigration>
在阅读了Alexander Derck的问题评论后,我得出了以下解决方案。我会把它贴在这里,以防其他人需要解决这个问题 然而,我个人认为这更像是一种黑客行为,而不是一种解决方案,因此我仍然对解决这一问题的正确方法感兴趣。在不质疑其有效性的情况下,不要将此答案复制粘贴到您的生产环境中强> 解决方案是在种子配置中添加一些代码。关注更多信息(复制自Alexander Derck的评论) 种子代码如下所示:
foreach (var tableBData in context.TableB.ToList())
{
if (tableB.TableA == null)
{
var tableA = new TableA();
tableB.TableB = tableA;
}
context.SaveChanges();
}
下面是引用的博客条目的摘录:
每当执行更新数据库PowerShell命令时,[迁移种子]就会运行。
除非使用迁移初始值设定项,否则迁移种子
方法将不会在应用程序启动时执行
为了触发迁移(默认为空,即不包含任何实际修改),我在迁移逻辑中添加了以下代码:
public partial class NameOfMyMigration : DbMigration
{
public override void Up()
{
AddColumn("dbo.TableA", "DummyField", c => c.Boolean(nullable: false, defaultValue: true));
DropColumn("dbo.TableA", "DummyField");
}
public override void Down()
{
}
}
当然,只有当这是新版本之前的最后一次迁移时,才需要进行此迁移,因为在此之后的任何迁移都会触发种子,因此不需要进行此迁移
不过,我还是觉得一定有更好的办法来解决这个问题 使用自动迁移 按照此MSDN博客文章中的说明进行操作 首先,您需要启用自动迁移。在PM控制台中,运行
启用迁移-EnableAutomaticMigrations
启用后,您可以使用命令添加迁移
和更新数据库
来完成所有繁重的工作
这将自动构建up和down方法,并将记录添加到数据库中
编辑:更新了当前版本的链接。我不确定是否理解您的需要,但我认为您的情况是,您已经编写了第一个项目的代码,并且数据库中已经充满了数据,现在您想添加新表,因此首先我尝试了解您的情况:
public class ApplicationDbContext : DbContext
{
public DbSet<ClassB> BList { get; set; }
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
public class ClassB
{
public ClassB()
{
BId = Guid.NewGuid().ToString();
}
[Key]
public string BId { get; set; }
}
并像前面一样将DbSet添加到上下文中:
public DbSet<ClassA> AList { get; set; }
现在我有两个表,和你们一样有一对多的关系
最后,我现在可以逐行编辑ClassB表了。
种子法:
protected override void Seed(ApplicationDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
context.BList.AddOrUpdate(
new ClassB { BId = Guid.NewGuid().ToString() },
new ClassB { BId = Guid.NewGuid().ToString() },
new ClassB { BId = Guid.NewGuid().ToString() }
);
}
context.AList.AddOrUpdate(
new ClassA { AId = Guid.NewGuid().ToString() },
new ClassA { AId = Guid.NewGuid().ToString() },
new ClassA { AId = Guid.NewGuid().ToString() }
);
protected override void Seed(ApplicationDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
var BArray = context.BList.ToArray();
var AArray = context.AList.ToArray();
for (int i = 0; i < BArray.Length; i++)
{
if (BArray.Length == AArray.Length)
{
BArray[i].AID = AArray[i].AId;
}
}
context.SaveChanges();
}
受保护的重写无效种子(ApplicationDbContext上下文)
{
//迁移到最新版本后将调用此方法。
//您可以使用DbSet.AddOrUpdate()助手扩展方法
//避免创建重复的种子数据。
//
var BArray=context.BList.ToArray();
var AArray=context.AList.ToArray();
for(int i=0;i
现在只需更新数据库它是有效的。在过去的好日子里,类似的事情可以通过触发器来完成。只是说(您可以从迁移配置类中种子)谢谢!我在seed类中添加了一些代码,可以根据需要添加记录。然而,为了让迁移触发seed逻辑,我必须使Up方法添加并删除一个伪列,否则seed代码将无法运行。我觉得这不是一个很棒的解决方案。。。有没有更好的方法来实现这一点?:)虽然正确,但问题中明确指出迁移已经设置,并且我确实运行了Add Migration命令来创建空迁移(因为没有涉及模型更改)。是的,但是“手动”迁移和自动迁移之间存在差异。启用自动迁移以能够使用此解决方案。我看不出自动迁移如何帮助我使用新的dataHi@havardhu更新现有表。我重新阅读了您的问题,我相信您是在问如何在TableA中自动添加表B中具有遗忘键的行。这是否正确?不,两个表都已经存在,它们之间的关系也是如此。唯一新的是,现在表a中必须有一个相关行,这以前不是一个要求。因此,我需要一种在不引入任何模型更改的情况下为数据播种的正确方法。我找到了一个解决方案(见我自己的答案),但它更像是一个黑客,而不是我书中的一个合适的解决方案。你不需要对种子数据进行任何模型更改。你只需要在种子方法中编写代码,然后执行更新数据库即可。
context.AList.AddOrUpdate(
new ClassA { AId = Guid.NewGuid().ToString() },
new ClassA { AId = Guid.NewGuid().ToString() },
new ClassA { AId = Guid.NewGuid().ToString() }
);
protected override void Seed(ApplicationDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
var BArray = context.BList.ToArray();
var AArray = context.AList.ToArray();
for (int i = 0; i < BArray.Length; i++)
{
if (BArray.Length == AArray.Length)
{
BArray[i].AID = AArray[i].AId;
}
}
context.SaveChanges();
}