entity framework多对多关系表创建“向后”
我遇到了EF6和多对多关系的问题。 我有以下设置:
public class Foo { public int Id { get; set; } public virtual ICollection Bars { get; set; } public virtual ICollection SubBars { get; set; } public Foo() { Bars = new HashSet(); SubBars = new HashSet(); } } public class Bar { public int Id { get; set; } public virtual ICollection Foos { get; set; } public Bar() { Foos = new HashSet(); } } public class SubBar { public int Id { get; set; } public virtual ICollection Foos { get; set; } public SubBar() { Foos = new HashSet(); } }
Foo
和Bar
之间的关系正常工作,DB中有一个名为BarFoos
的表。 然而, Foo
和SubBar
之间的关系是相反的。 DB中有一个名为FooSubBars
的表,它基本上保持正确的关系,但是像SubBar.AsQueryable().Include(sb => sb.Foos)
一样急切加载SubBar.AsQueryable().Include(sb => sb.Foos)
返回一个EntityCommandExecutionException
其中包含一个消息Invalid object name dbo.SubBarFoos
。
问题是:如何反转关系表名称以允许急切加载?
– 编辑 –
迁移中的数据库创建如下:
CreateTable( "dbo.BarFoos", c => new { Bar_Id = c.Int(nullable: false), Foo_Id = c.Int(nullable: false), }) .PrimaryKey(t => new { t.Bar_Id, t.Foo_Id }) .ForeignKey("dbo.Bars", t => t.Bar_Id, cascadeDelete: true) .ForeignKey("dbo.Foos", t => t.Foo_Id, cascadeDelete: true) .Index(t => t.Bar_Id) .Index(t => t.Foo_Id); CreateTable( "dbo.FooSubBars", c => new { Foo_Id = c.Int(nullable: false), SubBar_Id = c.Int(nullable: false), }) .PrimaryKey(t => new { t.Foo_Id, t.SubBar_Id }) .ForeignKey("dbo.Foos", t => t.Foo_Id, cascadeDelete: true) .ForeignKey("dbo.SubBars", t => t.SubBar_Id, cascadeDelete: true) .Index(t => t.Foo_Id) .Index(t => t.SubBar_Id);
在迁移中替换表名是否足够?
如果您在DbContext上覆盖OnModelCreating方法,则可以确保将表名生成为“FooBars”,如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity().HasMany(f => f.Bars).WithMany(b => b.Foos) .Map(m => m.ToTable("FooBars") // Optionally specify the key column names... .MapLeftKey("FooId") .MapRightKey("BarId") ); modelBuilder.Entity ().HasMany(f => f.SubBars).WithMany(sb => sb.Foos).Map(m => m.ToTable("FooSubBars")); }
这将在迁移中产生这种情况:
CreateTable( "dbo.FooBar", c => new { FooId = c.Int(nullable: false), BarId = c.Int(nullable: false), }) .PrimaryKey(t => new { t.FooId, t.BarId }) .ForeignKey("dbo.Foos", t => t.FooId, cascadeDelete: true) .ForeignKey("dbo.Bars", t => t.BarId, cascadeDelete: true) .Index(t => t.FooId) .Index(t => t.BarId); CreateTable( "dbo.FooSubBar", c => new { Foo_Id = c.Int(nullable: false), SubBar_Id = c.Int(nullable: false), }) .PrimaryKey(t => new { t.Foo_Id, t.SubBar_Id }) .ForeignKey("dbo.Foos", t => t.Foo_Id, cascadeDelete: true) .ForeignKey("dbo.SubBars", t => t.SubBar_Id, cascadeDelete: true) .Index(t => t.Foo_Id) .Index(t => t.SubBar_Id);
我也尝试在DbContext上查询SubBars时急切加载Foos,不会出现任何错误:
var context = new FooBarContext(); var subBars = from sb in context.SubBars.Include(i => i.Foos) select sb;
我可以通过在这里查看来反转命名
https://msdn.microsoft.com/en-us/library/jj591620(v=vs.113).aspx
只要Entity1和Entity2都具有彼此的导航属性,那么以下工作。
modelBuilder.Entity() .HasMany(t => t.Products) .WithMany(t => t.Orders);
哪个产生
CreateTable( "dbo.OrderProducts", c => new { Order_OrderID = c.Int(nullable: false), Product_ID = c.Int(nullable: false), }) .PrimaryKey(t => new { t.Order_OrderID, t.Product_ID }) .ForeignKey("dbo.Orders", t => t.Order_OrderID, cascadeDelete: true) .ForeignKey("dbo.Products", t => t.Product_ID, cascadeDelete: true) .Index(t => t.Order_OrderID) .Index(t => t.Product_ID);