Ef code first 使用codefirst或fluent API与同一实体的多对多(联接表)关系?

Ef code first 使用codefirst或fluent API与同一实体的多对多(联接表)关系?,ef-code-first,many-to-many,Ef Code First,Many To Many,我正在使用EF 4.3.1 CodeFirst进行开发。我有一张机场表,如下所示: public class Airport { [Key] public int ID { get; set; } public string Name{ get; set; } } 我需要的是一个路由表,其中包含来自同一机场表的2个FK,如: public class Route { public int Departu

我正在使用EF 4.3.1 CodeFirst进行开发。我有一张机场表,如下所示:

 public class Airport
    {
        [Key]
        public int ID { get; set; }
        public string Name{ get; set; }
    }
我需要的是一个路由表,其中包含来自同一机场表的2个FK,如:

 public class Route
    {
        public int DepartureAirportID { get; set; }
        public int DestinationAirportID { get; set; }
        public virtual Airport DestinationAirport { get; set; }
        public virtual Airport DepartureAirport { get; set; }
    }

如何实现这一点?

这应该满足您的需要

public class Airport
{
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Route> DepartureRoutes { get; set; }
    public virtual ICollection<Route> DestinationRoutes { get; set; }
}
public class Route
{
    public int DepartureAirportID { get; set; }
    public int DestinationAirportID { get; set; }
    public Airport DestinationAirport { get; set; }
    public Airport DepartureAirport { get; set; }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Route>()
        .HasKey(i => new { i.DepartureAirportID, i.DestinationAirportID});

    modelBuilder.Entity<Route>()
        .HasRequired(i => i.DepartureAirport)
        .WithMany(u => u.DepartureRoutes)
        .HasForeignKey(i => i.DepartureAirportID)
        .WillCascadeOnDelete(false);

    modelBuilder.Entity<Route>()
        .HasRequired(i => i.DestinationAirport)
        .WithMany(u => u.DestinationRoutes)
        .HasForeignKey(i => i.DestinationAirportID)
        .WillCascadeOnDelete(false);
}
…你可以这样使用它

using (var db = new MyDbContext())
{
    foreach (var routeid in Enumerable.Range(1, 100))
    {
        var departure = new Airport { Name = "departure" + routeid };
        db.Airports.Add(departure);
        var destination = new Airport { Name = "destination" + routeid };
        db.Airports.Add(destination);

        var route = new Route{ DepartureAirport = departure, DestinationAirport = destination };
        db.Routes.Add(route);
    }

    int recordsAffected = db.SaveChanges();

    foreach (var route in db.Routes)
    {
        Console.WriteLine("{0}, {1}, {2}, {3}", route.DepartureAirportID, route.DestinationAirportID, route.DepartureAirport.Name, route.DestinationAirport.Name);
    }
}
…希望这有帮助。 注意:不要在必需的属性上使用
virtual
(因为这些属性是索引-对于这种类型的映射,只能这样工作,我认为您会得到一些错误)。

另外,我总是添加相反的关系,但您可以使用WithMany()blank,也可以使用。

您应该向类Airport添加一个额外的自相关属性:

public class Airport
{
    public int ID { get; set; }
    public string Name{ get; set; }
    public virtual ICollection<Airport> AirportRoutes { get; set; }
}
公共级机场
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection AirportRoutes{get;set;}
}
并使用下一个Fluent API代码覆盖OnModelCreating方法:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Airport>().HasMany(x => x.AirportRoutes).WithMany().Map(
            x => 
               {
                   x.MapLeftKey("DepartureId");       // left key name
                   x.MapRightKey("DestinationId");    // right key name
                   x.ToTable("Routes");               // table name
               });
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity().HasMany(x=>x.AirportRoutes).WithMany().Map(
x=>
{
x、 MapLeftKey(“DepartureId”);//左键名称
x、 MapRightKey(“DestinationId”);//右键名称
x、 ToTable(“Routes”);//表名
});
}

希望这能对您有所帮助。

谢谢您!我是MVC新手。我使用的是EF 4.3.1。你能给我推荐一些最新和有效的来源来了解CodeFirst Fluent API和关系吗?在谷歌上给它一个“实体框架演练”(过去一年),这应该会给你很多。请关注[MS ADO.NET forums](),因为大多数问题都在那里被问到(尽管回答比较慢:)。顺便说一句,如果你觉得这个有用的话,也请“向上投票”!Nsaga我会这样做,即使它实际上“是”不是:)但上面的答案和你的努力将非常值得。但我不能,因为我得到了一个警告,“投票需要15个名声”。对不起,伙计:(好的:)对不起,我完全忘记了。还有一个链接我找到了这个工具,但它在构造函数上生成哈希集,所以我相信它不能处理最新版本的EF:[link]谢谢@Beebik。您是否建议将其作为我在对NSGaga的评论中提到的ALTER TABLE解决方案的替代方案?
protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Airport>().HasMany(x => x.AirportRoutes).WithMany().Map(
            x => 
               {
                   x.MapLeftKey("DepartureId");       // left key name
                   x.MapRightKey("DestinationId");    // right key name
                   x.ToTable("Routes");               // table name
               });
}