我想在ASP.NET MVC4中建立多对多的关系。
目标是使用属于用户的UserProfile
对象列表扩展默认的Timeline
类。
多个用户可以共享Timeline
,因此Timeline
类应该包含UserProfile
个对象的列表。
时间线课程:
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");
});
}
}
}
UserProfile类(具有添加属性的默认类):
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; }
}
我有一个带外键的连接表:
创建Timeline
的实例时,Users
列表为null
:
Timeline timeline = db.Timelines.Find(id); // timeline.Users = null
有人可以赐教,我应该如何设置它?
我是ASP.NET MVC4的新手。
编辑1:我知道我不应该扩展UserProfile,而是创建另一个类来存储用户。一旦多对多关系奏效,我将重构并朝着这个方向前进。 但首先我想知道它为什么不起作用。
编辑2: 双上下文也引起了问题,为两个上下文创建了两个数据库,其中一个纯连接表为空。
答案 0 :(得分:2)
我建议你完成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
这将运行两个单独的查询。第一次访问导航属性时会执行第二次。
BTW:您有两个上下文类 - TimelineContext
和UsersContext
的原因吗? “通常”你只需要一个上下文。
答案 1 :(得分:0)
我不喜欢搞乱内部用户配置文件的工作。我建议创建自己的用户类,将其链接到simplemembershipprovider并在那里添加功能。在最大程度上,您将稍微扩展帐户类以添加更多要注册的字段,但这就是它。
关注this非常方便的指南,让事情有效,如果您遇到错误,请告诉我。