我今天有另一个问题。
我想将ApplicationUser列表关联到应用程序用户......
像这样......
public class ApplicationUser : IdentityUser
{
//Here are the Added Needed Values to IdentityUser to PlenaMenteTrabajando Application.
public string FirstName { get; set; }
public string LastName { get; set; }
public ROLES Role { get; set;
public virtual ICollection<ApplicationUser> Brothers { get; set; }
public virtual ICollection<ApplicationUser> Parents{ get; set; }
public virtual ICollection<ApplicationUser> Sons { get; set; }
//Other Stuff
}
我不知道如何处理这些关系......
建立另一个存储兄弟,父母和儿子的实体?
像这样......
public class Brother
{
public int BrotherId{ get; set; }
public int UserId { get; set; }
public virtual ApplicationUser User { get; set; }
public virtual ICollection<ApplicationUser> Brothers{ get; set; }
}
或者我应该使用Fluent API来设置关系吗? (但我不知道怎么做)
或两者兼而有之?
感谢阅读!
答案 0 :(得分:0)
根据您希望使用此关系的方式,有多种方法可以实现此目的。存在与不同实现相关的性能问题。
例如,如果您必须对Parent,Brothers and Sons列表进行大量快速查询并且很少修改这些数据,您可以冗余地存储信息,因此您有一个Sons / Parents表和Brothers表,与这些关系的一些EF映射。这些表只存储相关人员的主键,每次修改其中一个关系(例如,添加新子)时,您必须在多个表中更新相同的信息。
但是,如果你必须进行大量的数据修改而不是那么多的查询,那么最好只存储Parents表,并且可以通过在那里进行查询来推断Brothers and Sons的列表。代码,但不是EF映射。
冗余表的示例:使用这些映射:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>().HasMany(u => u.Parents).WithMany(u => u.Sons).Map( x => { x.MapRightKey("ParentId"); x.MapLeftKey("SonId"); x.ToTable("ParentsSons"); } );
modelBuilder.Entity<ApplicationUser>().HasMany(u => u.Sons).WithMany(u => u.Parents);
modelBuilder.Entity<ApplicationUser>().HasMany(u => u.Brothers).WithMany().Map(x => { x.MapRightKey("BrotherId"); x.MapLeftKey("Id"); x.ToTable("Brothers"); });
}
迁移包括这些表(为了简单起见,我向ApplicationsUsers实体添加了一个整数Id
属性):
CreateTable(
"dbo.ApplicationUsers",
c => new
{
Id = c.Int(nullable: false, identity: true),
FirstName = c.String(),
LastName = c.String(),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Brothers",
c => new
{
Id = c.Int(nullable: false),
BrotherId = c.Int(nullable: false),
})
.PrimaryKey(t => new { t.Id, t.BrotherId })
.ForeignKey("dbo.ApplicationUsers", t => t.Id)
.ForeignKey("dbo.ApplicationUsers", t => t.BrotherId)
.Index(t => t.Id)
.Index(t => t.BrotherId);
CreateTable(
"dbo.ParentsSons",
c => new
{
SonId = c.Int(nullable: false),
ParentId = c.Int(nullable: false),
})
.PrimaryKey(t => new { t.SonId, t.ParentId })
.ForeignKey("dbo.ApplicationUsers", t => t.SonId)
.ForeignKey("dbo.ApplicationUsers", t => t.ParentId)
.Index(t => t.SonId)
.Index(t => t.ParentId);
使用这些表稍微玩一下的示例方法。如果通过它进行调试,则可以检查实体并检查“父母和子”列表的内容。 TestContext
仅包含一个DbSet
用户:public DbSet<ApplicationUser> Users { get; set; }
public void Test()
{
using (var context = new TestContext())
{
var arya = new ApplicationUser()
{
FirstName = "Arya",
Parents = new List<ApplicationUser>
{
new ApplicationUser { FirstName = "Eddard" },
new ApplicationUser { FirstName = "Catelyn" }
}
};
context.Users.Add(arya);
context.SaveChanges();
var eddard = context.Users.First(u => u.FirstName == "Eddard");
var jon = new ApplicationUser { FirstName = "Jon" };
eddard.Sons.Add(jon);
context.SaveChanges();
var eddardFromContext = context.Users.First(u => u.FirstName == "Eddard");
var catelynFromContext = context.Users.First(u => u.FirstName == "Catelyn");
}
}
我离开了兄弟名单。请注意,EF不会自动将兄弟数据与Parents / Sons数据同步。因此,在将用户添加到“父/子”列表时,您必须明确地将用户添加到“兄弟”列表中。但是,Parent and Sons列表会自动同步:如果您将用户A添加到用户B的Parents列表并保留数据,则用户B的Parents列表将包含用户A.这是因为Parents和Sons的映射使用了相同的导航属性。 Brothers属性不会发生这种情况。