2013-06-30 16 views
0

我想在ASP.NET MVC4中建立多對多的關係。 目標是使用屬於該用戶的一列Timeline對象擴展默認的UserProfile類。 A Timeline可以由多個用戶共享,所以Timeline類也應該有一個UserProfile對象的列表。多對多關係,結表不被識別

Timeline類:

namespace MvcApplication1.Models 
{ 
    public class Timeline 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public string Color { get; set; } 
     public List<UserProfile> Users { get; set; } 
    } 

    public class TimelineContext : DbContext 
    { 
     public DbSet<Timeline> Timelines { get; set; } 
     public DbSet<UserProfile> UserProfiles { get; set; } 

     // Added the following because I saw it on: 
     // http://www.codeproject.com/Tips/548945/Generating-Many-to-Many-Relation-in-MVC4-using-Ent 
     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      base.OnModelCreating(modelBuilder); 

      modelBuilder.Entity<Timeline>() 
       .HasMany(c => c.Users) 
       .WithMany(s => s.Timelines) 
       .Map(mc => 
       { 
        mc.ToTable("TimelineOwners"); 
        mc.MapLeftKey("TimelineId"); 
        mc.MapRightKey("UserId"); 
       }); 
     } 
    } 
} 

用戶配置類(與添加的屬性默認類):

public class UsersContext : DbContext 
{ 
    public UsersContext() 
     : base("DefaultConnection") 
    { 
    } 

    public DbSet<UserProfile> UserProfiles { get; set; } 
    public DbSet<Timeline> Timelines { get; set; } 

    // Added the following because I saw it on: 
    // http://www.codeproject.com/Tips/548945/Generating-Many-to-Many-Relation-in-MVC4-using-Ent 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<UserProfile>() 
      .HasMany(c => c.Timelines) 
      .WithMany(s => s.Users) 
      .Map (mc => 
       { 
        mc.ToTable("TimelineOwners"); 
        mc.MapLeftKey("UserId"); 
        mc.MapRightKey("TimelineId"); 
       }); 
    } 
} 

[Table("UserProfile")] 
public class UserProfile 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int UserId { get; set; } 
    public string UserName { get; set; } 

    public List<Timeline> Timelines { get; set; } 
} 

我有一個外鍵連接表:

enter image description here

enter image description here

enter image description here

當創建的Timeline的情況下,Users名單null

Timeline timeline = db.Timelines.Find(id); // timeline.Users = null 

可有人請賜教,我應該怎麼設置這工作?

我完全是ASP.NET MVC4的新手。

編輯1:我知道我不應該擴展UserProfile,但創建另一個類來存儲用戶。一旦多對多關係有效,我會重構並進入這個方向。但是首先我想知道它爲什麼不起作用。

編輯2: 雙上下文也導致問題,兩個數據庫創建爲兩個上下文和純連接表是其中一個是空的。

回答

1

我建議你通過this article about the options how you can load navigation properties with Entity Framework工作。這是非常基礎的知識,對每種關係都很重要,不僅是多對多的關係。

看着這篇文章,你會發現那麼這條線......

Timeline timeline = db.Timelines.Find(id); 

...不加載任何相關的實體。因此,即使實體在數據庫中相關,預計timeline.Users也是null

如果要加載Users可以使用預先加載

Timeline timeline = db.Timelines.Include(t => t.Users) 
    .SingleOrDefault(t => t.Id == id); 

這是一個單獨的數據庫查詢。或使延遲加載你必須爲virtual標記你的導航性能:

public virtual List<UserProfile> Users { get; set; } 

//... 

public virtual List<Timeline> Timelines { get; set; } 

然後,您可以使用您的原始代碼:

Timeline timeline = db.Timelines.Find(id); // first query 
var users = timeline.Users;    // second query 

這將運行兩個單獨的查詢。第二次只要您第一次訪問導航屬性就會執行。

順便說一句:有沒有一個原因,你爲什麼有兩個上下文類 - TimelineContextUsersContext? 「通常情況下」你只需要一個上下文。

+0

謝謝。雙上下文也造成了問題,兩個上下文創建了兩個數據庫,其中一個上的純連接表爲空。糾正這些後,它工作正常。 –

0

我不喜歡搞亂內部userprofile的工作。我建議創建自己的用戶類,將其鏈接到simplemembershipprovider並在其中添加功能。在最大限度內,您可以稍微擴展帳戶類以添加更多的字段進行註冊,但僅此而已。

跟着this非常方便的指南讓事情正常工作,讓我知道如果你遇到一個錯誤。

+0

謝謝。除此之外,爲什麼多對多關係不起作用? –