6

这可能只是因为我对EF Code First流利API的知识不足,但我很难过。EF代码优先:多对多和一对多

我想如下建模:

  • 一个收集与编号和名称
  • 一个用户收集与编号和名称
  • 每个用户都被分配到一个主组
  • 每个用户可能有零个或多个第二组

表结构我要为会是什么样子:

  • 编号
  • 名称

用户

  • 个编号
  • 名称
  • PrimaryGroupId

SecondaryGroupAssignments

  • 用户ID
  • 的GroupId

我一直在打我的头撞墙试图模拟这种与EF代码第一,布我无法接受用户和组之间的这两种关系。对不起,没有发布任何.NET代码(我很高兴),但它可能都是错的。

有没有办法让EF模型呢?我假设我必须使用Fluent API进行某种配置。也许更好的问题是:Fluent API是否有很好的明确参考?

谢谢!

回答

16

试试这个(未经测试):

public class Group 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<User> PrimaryUsers { get; set; } 
    public virtual ICollection<User> SecondaryUsers { get; set; } 
} 

public class User 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int PrimaryGroupId { get; set; } 

    public virtual Group PrimaryGroup { get; set; } 
    public virtual ICollection<Group> SecondaryGroups { get; set; } 
} 

public class Context : DbContext 
{ 
    public DbSet<User> Users { get; set; } 
    public DbSet<Group> Groups { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<User>() 
        .HasRequired(u => u.PrimaryGroup) 
        .WithMany(g => g.PrimaryUsers) 
        .HasForeignKey(u => u.PrimaryGroupId) 
        .WillCascadeOnDelete(false); 

     modelBuilder.Entity<User>() 
        .HasMany(u => u.SecondaryGroups) 
        .WithMany(g => g.SecondaryUsers) 
        .Map(m => m.MapLeftKey("UserId") 
           .MapRightKey("GroupId") 
           .ToTable("SecondaryGroupAssignments")); 
    } 
} 
+3

我可以说拉迪斯拉夫,这是我曾经有幸遇到过/用来解决我确切问题的最有用的帖子之一!谢谢! – LiverpoolsNumber9 2011-11-03 16:48:09

+0

Lad是实体框架的人,非常感谢拥有如此丰富的资源。还有一个原因是这个栈太棒了! – Sam 2012-08-12 17:46:33

3

基于拉吉斯拉夫出色的答案,这里是如何做到这一点,而无需使用任何映射 - 只是属性应用到模型类本身:

public class Group 
{ 
    public int Id { get; set; } 

    [MaxLength(300)] 
    public string Name { get; set; } 

    public ICollection<User> Users { get; set; } 
} 

public class User 
{ 
    public int Id { get; set; } 

    [MaxLength(300)] 
    public string Name { get; set; } 

    [ForeignKey("PrimaryGroup")] 
    public int PrimaryGroupId { get; set; } 
    [Required] 
    public Group PrimaryGroup { get; set; } 

    [InverseProperty("Users")] 
    public ICollection<Group> SecondaryGroups { get; set; } 
} 

注意事项

如果需要,可以将虚拟关键字添加到2 ICollectionGroup。这allows lazy-loading。在性能方面,我不推荐它,但它是可能的。

我包含的MaxLength属性的任意(但安全)长度为300,因为在没有MaxLength的情况下将字符串放在EF中可以获得低性能的NVarChar(MAX)列。完全不相关的问题,但更好地发布好的代码。

我建议您的EF类的类名称为“User”和“Group”。他们会让你以后尝试运行的任何SQL复杂化,必须键入[User]和[Group]才能访问它们,并且在类别User将与Context属性User冲突的MVC控制器中使用这些类会变得复杂访问Asp.Net Identity库。

+0

我希望我可以对此答案进行两次投票!非常感谢Chris ... – stt106 2015-11-08 20:56:30

相关问题