【问题标题】:Many-to-Many Relationship, junction table not recognized多对多关系,无法识别连接表
【发布时间】:2013-07-01 06:26:57
【问题描述】:

我想在 ASP.NET MVC4 中建立多对多关系。 目标是使用属于用户的Timeline 对象列表扩展默认的UserProfile 类。 一个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: 双重上下文也引起了问题,为这两个上下文创建了两个数据库,其中一个纯连接表为空。

【问题讨论】:

    标签: asp.net asp.net-mvc entity-framework asp.net-mvc-4


    【解决方案1】:

    我建议您通过this article about the options how you can load navigation properties with Entity Framework 工作。这是非常基础的知识,对每一种关系都很重要,而不仅仅是多对多关系。

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

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

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

    如果你想加载Users,你可以使用eager loading

    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 有什么原因吗? “通常”你只需要一个上下文。

    【讨论】:

    • 谢谢。双重上下文也引起了问题,为这两个上下文创建了两个数据库,其中一个中的纯连接表为空。更正这些后,它工作正常。
    【解决方案2】:

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

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

    【讨论】:

    • 谢谢。除此之外,为什么多对多关系不起作用?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 2016-02-18
    • 1970-01-01
    • 2015-03-22
    • 2012-05-19
    相关资源
    最近更新 更多