2013-06-30 19 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

谢谢。除此之外,为什么多对多关系不起作用? –