2012-04-06 32 views
4

我正在用EF 4.3.1 CodeFirst进行开发。我有一个机场表,如下图所示:与codefirst或fluent API使用同一个实体的多对多(连接表)关系?

public class Airport 
    { 
     [Key] 
     public int ID { get; set; } 
     public string Name{ get; set; } 
    } 

我需要的是一个路由表与喜欢同样的机场表2个FKS:

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; } 
    } 

如何才能实现这一目标?

回答

3

这应该做你需要什么...

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); 
} 

...这将创建类似的表...

CREATE TABLE [Airports] (
    [ID] [int] NOT NULL IDENTITY, 
    [Name] [nvarchar](4000), 
    CONSTRAINT [PK_Airports] PRIMARY KEY ([ID]) 
) 
CREATE TABLE [Routes] (
    [DepartureAirportID] [int] NOT NULL, 
    [DestinationAirportID] [int] NOT NULL, 
    CONSTRAINT [PK_Routes] PRIMARY KEY ([DepartureAirportID], [DestinationAirportID]) 
) 
CREATE INDEX [IX_DestinationAirportID] ON [Routes]([DestinationAirportID]) 
CREATE INDEX [IX_DepartureAirportID] ON [Routes]([DepartureAirportID]) 
ALTER TABLE [Routes] ADD CONSTRAINT [FK_Routes_Airports_DestinationAirportID] FOREIGN KEY ([DestinationAirportID]) REFERENCES [Airports] ([ID]) 
ALTER TABLE [Routes] ADD CONSTRAINT [FK_Routes_Airports_DepartureAirportID] FOREIGN KEY ([DepartureAirportID]) REFERENCES [Airports] ([ID]) 

...你可以使用它是这样的...

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()空白,也应该工作。

+0

谢谢NSGaga!我是MVC的新手。我正在使用EF 4.3.1。您能否向我推荐任何最新且有效的来源来了解CodeFirst Fluent API和关系? – oislek 2012-04-06 23:38:30

+0

在谷歌(过去一年)给它一个'实体框架演练' - 这应该给你足够的。遵循[MS ADO.NET论坛](http://blogs.msdn.com/b/adonet/),因为大部分事情都在那里被问到(尽管响应速度较慢:)。顺便说一句,请'upvote',如果你觉得这个有用! – NSGaga 2012-04-06 23:46:57

+0

Nsaga我会做它,即使它实际上“是”不是:)但上面的答案和你的努力将非常值得。但我不能因为“投票需要15点声望”而受到警告。对不起伙伴:( – oislek 2012-04-06 23:50:50

0

你应该额外的自相关属性添加到您的类机场:

public class Airport 
{ 
    public int ID { get; set; } 
    public string Name{ get; set; } 
    public virtual ICollection<Airport> AirportRoutes { get; set; } 
} 

,并覆盖OnModelCreating方法与下一流利的API代码:

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 
       }); 
} 

希望这有助于你。

+0

谢谢@Beebik。您是否推荐将此作为我在我的评论中提到的NSGaga的ALTER TABLE解决方案的替代方案? – oislek 2012-04-19 10:30:43

相关问题