【问题标题】:Entity Framework Code First Collection Mapping - FriendRequests实体框架代码优先集合映射 - FriendRequests
【发布时间】:2012-03-27 14:30:22
【问题描述】:

我需要首先使用实体​​框架代码映射多对多关系。它是一个标准的社交网络FriendRequests 映射。一个用户对象有一个类型为List<User> 的FriendRequests 集合。在数据库中,我使用的是连接表,如下所示:

CREATE TABLE dbo.FriendRequests(
  UserId INT NOT NULL FOREIGN KEY REFERENCES dbo.Users(id),
  FriendId INT NOT NULL FOREIGN KEY REFERENCES dbo.Users(id),
  RequestDate SMALLDATETIME NOT NULL DEFAULT GETUTCDATE())
GO
ALTER TABLE dbo.FriendRequests ADD PRIMARY KEY (UserId,FriendId) 
GO

如何在 Entity Framework Code First 中映射用户对象以通过连接表启用集合?

【问题讨论】:

    标签: entity-framework-4 entity-framework-4.1


    【解决方案1】:

    你可以这样试试:

    public class User
    {
        public int Id { get; set; }
    
        public ICollection<FriendRequest> FriendRequests { get; set; }
    }
    
    public class FriendRequest
    {
        public int UserId { get; set; }
        public int FriendId { get; set; }
    
        public DateTime RequestDate { get; set; }
    
        public User User { get; set; }
        public User Friend { get; set; }
    }
    

    使用 Fluent API 进行映射:

    modelBuilder.Entity<User>()
        .HasMany(u => u.FriendRequests)
        .WithRequired(f => f.User)
        .HasForeignKey(f => f.UserId);
    
    modelBuilder.Entity<FriendRequest>()
        .HasKey(f => new { f.UserId, f.FriendId });
    
    modelBuilder.Entity<FriendRequest>()
        .HasRequired(f => f.Friend)
        .WithMany()
        .HasForeignKey(f => f.FriendId);
    

    由于链接表中的RequestDate 属性,您不能将其映射为多对多关系。相反,您需要两个一对多关系,如上所示。

    您可能需要禁用级联删除,我不确定。您可以通过在两个一对多映射的末尾附加 .WillCascadeOnDelete(false) 来做到这一点。

    编辑

    对于您的评论:如果您删除 RequestDate 列,您可以创建具有多对多关系的模型。在这种情况下,您不需要 FriendRequest 实体:

    public class User
    {
        public int Id { get; set; }
    
        public ICollection<User> FriendRequests { get; set; }
    }
    

    使用 Fluent API 进行映射:

    modelBuilder.Entity<User>()
        .HasMany(u => u.FriendRequests)
        .WithMany()
        .Map(m =>
        {
            m.ToTable("FriendRequests");
            m.MapLeftKey("UserId");
            m.MapRightKey("FriendId");
        });
    

    【讨论】:

    • RequestDate 属性不是必需的。如果我删除该列,有没有办法以多对多的方式进行操作?
    • @reach4thelasers:是的,看我的编辑。
    • 感谢您的回复。我尝试了您的代码并将一些示例数据放入连接表中进行测试,但对于 user.FriendRequests.Count(),我总是得到 0。我需要做些什么来获取 Joined 集合吗?
    • @reach4thelasers:你如何加载user?如果您没有将集合属性声明为 virtual(= 没有延迟加载),您需要预先加载(= Include)集合,例如:var user = context.Users.Include(u =&gt; u.FriendRequests)....
    • 谢谢!!将所有内容设置为虚拟使其工作得很好!感谢您的及时答复!
    猜你喜欢
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 2011-04-21
    • 2012-05-18
    相关资源
    最近更新 更多