【问题标题】:Entity Framework define complex object relationship实体框架定义复杂的对象关系
【发布时间】:2016-04-13 19:52:24
【问题描述】:

我有一个 UserFollowing 类定义如下:

public class User : IdentityUser
{
    public User()
    {
        Followers = new HashSet<Following>();
        Following = new HashSet<Following>();
    }

    [Key]
    public string ID { get; set; }
...
...

    public virtual ICollection<Following> Followers { get; set; }

    public virtual ICollection<Following> Following { get; set; } 
}

public class Following
{
        [Key]        
        public int ID {get;set;}

        [MaxLength(100)]
        public string follower { get; set; }

        [MaxLength(100)]
        public string following { get; set; }           

        public virtual User UserFollower { get; set; }

        public virtual User UserFollowing { get; set; }
 }

Following中的属性follower和following都是User对象的外键,代表关系。然后在 DBcontext 类中,我将覆盖 OnModelCreating:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {      
        modelBuilder.Entity<User>()
            .HasMany<Following>(u => u.Followers)
            .WithOptional()
            .HasForeignKey(c => c.following);

        modelBuilder.Entity<User>()
            .HasMany<Following>(u => u.Following)
            .WithOptional()
            .HasForeignKey(c => c.follower);
}

这非常适合获取用户的关注者和关注者:

User user = await UserManager.FindByIdAsync(ID);
List<Following> followers = user.Following.ToList();

我的基本问题是如何创建 UserFollower 和 UserFollowing 关系,以便将 Following 的这些属性中的每一个都映射到用户?

理想情况下,我可以按照以下方式做一些事情:

User user = await UserManager.FindByIdAsync(ID);
List<Following> followers = user.Following.ToList();

User userFollowing = followers[0].UserFollowing;

【问题讨论】:

    标签: c# asp.net .net entity-framework


    【解决方案1】:

    稍微修改你的模型

    public class User : IdentityUser
    {
        public User()
        {
            // Don't do this. Entity Framwork will do that for you
            // Followers = new HashSet<Following>();
            // Following = new HashSet<Following>();
        }
    
        // Don't add this. IdentityUser has already defined it as `Id`
        // [Key]
        // public string ID { get; set; }
    
        public virtual ICollection<Following> Followers { get; set; }
    
        public virtual ICollection<Following> Following { get; set; } 
    }
    
    public class Following
    {
        [Key]        
        public int ID {get;set;}
    
        // [MaxLength(100)] No need to do this as this is Foreign Key Property
        public string follower { get; set; }
    
        // [MaxLength(100)] No need to do this as this is Foreign Key Property
        public string following { get; set; }           
    
        public virtual User UserFollower { get; set; }
    
        public virtual User UserFollowing { get; set; }
    }
    

    然后是用户流畅的 API 来定义关系

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {      
        modelBuilder.Entity<User>()
            .HasMany(u => u.Followers)
            .WithRequired(f => f.UserFollower)
            .HasForeignKey(c => c.following);
    
        modelBuilder.Entity<User>()
            .HasMany(u => u.Following)
            .WithRequired(f => f.UserFollowing)
            .HasForeignKey(c => c.follower);
    }
    

    这将创建一个双向关系。进一步的 EntityFramework 将覆盖所有虚拟属性并定义您期望的行为。

    如果您没有修改 EntityFramework 配置,您将可以直接这样做

    User user = await UserManager.FindByIdAsync(ID);
    List<Following> followers = user.Following.ToList();
    
    User userFollowing = followers[0].UserFollowing;
    

    【讨论】:

    • 你是对的。我在使用他们自己的文档的构造函数中绝对不需要 HashSet,但意识到这没有必要。非常感谢,我更喜欢你的 Fluent API 使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    相关资源
    最近更新 更多