如何在FluentAPI映射表中插入数据

时间:2015-10-28 18:29:59

标签: entity-framework crud ef-fluent-api

我有A表,B表和AB(映射表)

A

public class A
{
    public int AID{ get; set; }

    [JsonIgnore]
    public virtual ICollection<B> Bs { get; set; }
}

public class B
{
    public int BID { get; set; }

    [JsonIgnore]
    public virtual ICollection<A> As { get; set; }
}

ApplicationDbContext

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<B>()
                    .HasMany(s => s.As)
                    .WithMany(c => c.Bs)
                    .Map(cs =>
                    {
                        cs.MapLeftKey("AID");
                        cs.MapRightKey("BID");
                        cs.ToTable("AB");
                    });

    }

现在情况非常好,但我如何在这个AB Mapping表中插入?

如果我尝试创建AB,如下所示,它会生成两个表,AB和AB1具有相同的列名和所有。

public class AB
{
    public int ABID { get; set; }
    public string AID { get; set; }
    public int BID { get; set; }
}
  1. 那么有没有办法在FluentAPI映射表中进行CRUD?
  2. 如果没有,那么我可以强制FluentAPI从现有表映射吗?在这种情况下,我将手动管理Employee,并将映射代码更改为使用现有表。
  3. 我无法找到任何解决方案。

1 个答案:

答案 0 :(得分:1)

编辑:由于问题已更改,我正在撰写更全面的答案。然而,你的问题的答案仍然是相同的:

  

现在情况非常好,但我如何在此AB Mapping中插入   表

你没有!

这正是EF擅长的那种东西。现在,您最终得到的是您想要的实际对象,而不是自己管理链接表。因此,如果您要在AB之间添加链接,您只需在B上的Bs集合中添加A即可。您不会直接插入AB表,因为谁在乎这个?该表就在那里,所以我们可以在不同的AB之间建立关系,就是这样。因此,实体框架将创建表供自己使用,但不会呈现给您,因为这不是EF的工作原理:您使用对象并让EF处理数据库。

这就是为什么当你尝试自己定义表时,它会创建两个:它已经创建了一个名为AB的表,但是你要求另一个表。它不能具有完全相同的名称,因此它会在其末尾添加“1”。由于您已经使用FluentAPI来定义应用程序,因此让EF担心如何实现映射:您需要关心的是,您现在有办法让A具有一组{ {1}} s,反之亦然。

由于这仍然让名字'A'和'B'听起来令人困惑,下面是控制台应用程序的B类,它将说明这一点;您需要做的就是启动一个全新的控制台应用程序,用这个替换Program类,安装实体框架包,然后运行Program。我建议您使用它来添加一些对象并将它们联系起来,然后去查看您的数据库:您将看到“AB”表,其中包含已添加的记录。这可能有助于更好地解释它。

enable-migrations -enableautomaticmigrations -force

旧答案:您已在class Program { static bool quit = false; static void Main(string[] args) { string s = "Please select an option:" + "\n1: Insert an A" + "\n2: Insert a B" + "\n3: Add a B to an A" + "\n4: Add an A to a B" + "\n5: Print all As" + "\n6: Print all Bs" + "\n7: Print AB Table" + "\nx: Quit."; while (!quit) { Console.WriteLine(); Console.WriteLine(s); var k = Console.ReadKey(); DoStuff(k); } } private static void DoStuff(ConsoleKeyInfo i) { switch (i.Key) { case ConsoleKey.D1: //add an A AddA(GetName()); break; case ConsoleKey.D2: //add a B AddB(GetName()); break; case ConsoleKey.D3: // link a B to an A LinkB(GetBtoLink(),GetAtoLink()); break; case ConsoleKey.D4: //link an A to an B LinkA(GetAtoLink(), GetBtoLink()); break; case ConsoleKey.D5: // print As WriteA(); break; case ConsoleKey.D6: //print Bs WriteB(); break; case ConsoleKey.D7: // print AB WriteAB(); break; case ConsoleKey.X: quit = true; break; } } private static int GetAtoLink() { string x; int z; do { Console.Clear(); Console.WriteLine("Please enter the ID of the A you want to use and then press enter."); WriteA(); x = Console.ReadLine(); } while (!int.TryParse(x, out z)); return z; } private static int GetBtoLink() { string x; int z; do { Console.Clear(); Console.WriteLine("Please enter the ID of the B you want to use and then press enter."); WriteB(); x = Console.ReadLine(); } while (!int.TryParse(x, out z)); return z; } private static void WriteB() { Console.WriteLine("{0,10}{1,15}", "ID", "Name"); using (var db = new Context()) { foreach (var a in db.Bs) { Console.WriteLine("{0,10}{1,15}", a.BID, a.Name); } } } private static void WriteA() { Console.WriteLine("{0,10}{1,15}", "ID", "Name"); using (var db = new Context()) { foreach (var a in db.As) { Console.WriteLine("{0,10}{1,15}", a.AID, a.Name); } } } private static void WriteAB() { Console.WriteLine("{0,10}{1,10}", "AID", "BID"); using (var db = new Context()) { // this is the only way we need to do this, because it's many to many, // if an A is linked to a B, then that B is by definition linked to that A as well. foreach (var a in db.As) { foreach (var b in a.Bs) { Console.WriteLine("{0,10}{1,10}", a.AID, b.BID); } } } } private static void LinkB(int bToUse, int aToUse) { using (var db = new Context()) { var a = db.As.First(x => x.AID == aToUse); var b = db.Bs.First(y => y.BID == bToUse); a.Bs.Add(b); db.SaveChanges(); } } private static void LinkA(int aToUse, int bToUse) { using (var db = new Context()) { var a = db.As.First(x => x.AID == aToUse); var b = db.Bs.First(y => y.BID == bToUse); b.As.Add(a); db.SaveChanges(); } } private static string GetName() { Console.WriteLine("Please enter a name"); return Console.ReadLine(); } private static void AddA(string input) { using (var db = new Context()) { db.As.Add(new A {Name = input}); db.SaveChanges(); } } private static void AddB(string input) { using (var db = new Context()) { db.Bs.Add(new B { Name = input }); db.SaveChanges(); } } } public class A { public int AID { get; set; } public string Name { get; set; } public virtual ICollection<B> Bs { get; set; } } public class B { public int BID { get; set; } public string Name { get; set; } public virtual ICollection<A> As { get; set; } } public class Context : DbContext { protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<B>() .HasMany(s => s.As) .WithMany(c => c.Bs) .Map(cs => { cs.MapLeftKey("AID"); cs.MapRightKey("BID"); cs.ToTable("AB"); }); } public DbSet<A> As { get; set; } public DbSet<B> Bs { get; set; } } 中定义了一个名为ICollection<ApplicationUser>的{​​{1}},并使用FluentAPI映射到该Employees。这会按预期创建一个名为“Employees”的表。您不必创建另一个名为Employees的类;就实体框架而言,您已经告诉它创建一个名为Employees的表。这就是为什么 我认为您缺少的步骤是定义您的Company

使用您的代码并运行DbSet<>,这是我为Employees表获得的定义:

Add-Migration

这似乎与你想要的相关。

要完成此操作,请将此(如果您尚未添加)添加到CreateTable( "dbo.Employees", c => new { UserID = c.Int(nullable: false), CompanyID = c.Int(nullable: false), }) .PrimaryKey(t => new { t.UserID, t.CompanyID }) .ForeignKey("dbo.ApplicationUsers", t => t.UserID, cascadeDelete: true) .ForeignKey("dbo.Companies", t => t.CompanyID, cascadeDelete: true) .Index(t => t.UserID) .Index(t => t.CompanyID); 文件中:

ApplicationDbContext

然后,要添加员工,请创建新的public DbSet<ApplicationUser> Employees; public DbSet<Company> Companies; 并将其添加为

ApplicationUser

ApplicationUser user = new ApplicationUser(); // do whatever here to give it the right data ApplicationDbContext ctx = new ApplicationDbContext(); ctx.Employees.Add(user); 表本身,您不应该与之交互。