0

我想在 ASP.NET MVC4 中建立多对多关系。目标是使用属于用户的对象列表扩展默认UserProfile类。TimelineATimeline可以由多个用户共享,因此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; }
}

我有一个带有外键的连接表:

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

创建 的实例时TimelineUsers列表为null

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

有人可以启发我,我应该如何设置它?

我对 ASP.NET MVC4 完全陌生。

编辑 1:我知道我不应该扩展 UserProfile 而是创建另一个类来存储用户。一旦多对多关系起作用,我将重构并朝那个方向发展。但首先我想知道为什么它不起作用。

编辑2: 双重上下文也引起了问题,为这两个上下文创建了两个数据库,其中一个纯连接表为空。

4

2 回答 2

2

我建议您阅读这篇文章,了解如何使用 Entity Framework 加载导航属性的选项。这是非常基础的知识,对每一种关系都很重要,不仅仅是多对多关系。

看那篇文章你会发现那一行……

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

...不加载任何相关实体。因此,即使实体在数据库中是相关的,也是如此timeline.Usersnull

如果要加载,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?“通常”你只需要一个上下文。

于 2013-06-30T21:17:29.450 回答
0

我不喜欢搞乱内部用户配置文件的工作。我建议创建您自己的用户类,将其链接到 simplemembershipprovider 并在那里添加功能。最多您将稍微扩展帐户类以添加更多要注册的字段,但仅此而已。

按照这个非常方便的指南让事情正常进行,如果您遇到错误,请告诉我。

于 2013-06-30T17:40:11.083 回答