大佬教程收集整理的这篇文章主要介绍了EF Core 自身之间的关系映射 测试 1测试 2,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
假设数据库中有两个表
@H_116_7@member
ID | 姓名 |
---|---|
1 | 托尼 |
2 | 史蒂夫 |
3 | 布鲁斯 |
4 | 斯科特 |
@H_116_7@memberRecruit
会员编号 | RecruitmentMemberID |
---|---|
1 | 2 |
1 | 3 |
2 | 4 |
RecruitmentMemberID
就是 @H_116_7@memberID
还有两个类
public class Member
{
public int id { get; set; }
public String name { get; set; }
public IList<MemberRecruit> Recruits { get; set; }
}
public class MemberRecruit
{
public int MemberID { get; set; }
public int RecruitmentMemberID { get; set; }
}
使用 EF Core 3.1,可以轻松地在 DbContext 中为 Ownsmany
创建 @H_116_7@member.Recuits 关系,例如
builder.Entity<Member>(m =>
{
m.@R_10_10586@ble("Member","dbo");
m.HasKey(x => x.MemberID);
m.Ownsmany(x => x.Recruits,nav =>
{
nav.@R_10_10586@ble("MemberRecruit","dbo");
nav.HasKey(x => new
{
x.MemberID,x.RecruitmentMemberID
});
nav.Withowner().HasForeignKey(x => x.MemberID);
});
});
如果我想将类结构更改为类似
public class Member
{
public int id { get; set; }
public String name { get; set; }
public IList<MemberRecruit> Recruits { get; set; }
}
public class MemberRecruit
{
public int MemberID { get; set; }
public int RecruitmentMemberID { get; set; }
public Member Recruitment { get; set; } // This is the recruited member
}
在不更改表的情况下,是否有一种很好的做法可以使用 Owns
或 .HasOne.WithMany + .Hasmany.WithOne
关系在 DbContext 中使用 FluentAPI 映射它,以便当我有 DbSet<Member> Members
时,我可以像这样查询以下?
var recruitments = (await _db.Members.AsnoTrack()
.Include(x => x.Recruits)
.FirstOrDefaultAsync(x => x.ID == request.ID,token))
.Recruits
.SELEct(x => x.Recruitment,token);
return recruitments.SELEct(x => (x.ID,x.Name));
// if request.ID is 1,return will be [(2,"Steve"),(3,"Bruce")]
// if request.ID is 2,return will be [(4,"Scott")]
// if request.ID is 3,return will be []
或者用同样的两张表,映射下面的类
public class Member
{
public int id { get; set; }
public String name { get; set; }
public IList<Member> Recruitments { get; set; }
}
这样查询就可以简化为
var member = await _db.Members.AsnoTrack()
.Include(x => x.Recruitments)
.FirstOrDefaultAsync(x => x.ID == request.ID,token);
return member.Recruitments.SELEct(x => (x.ID,x.Name));
builder.Entity<Member>(m =>
{
m.@R_10_10586@ble("Member",x.RecruitmentMemberID
});
nav.Withowner().HasForeignKey(x => x.MemberID);
nav.HasOne(x => x.Member) // Added HasOne.WithMany
.WithMany(x => x.Recruits)
.HasForeignKey(x => x.RecruitmentMemberID);
});
});
这次回归
var member = await _db.Members.AsnoTrack()
.Include(x => x.Recruits)
.FirstOrDefaultAsync(x => x.ID == 1,token);
// member.Recurits.Count is 1 instead of 2
// member.Recurits[0].Recruitment.ID is 1 which is incorrect
@H_197_149@测试 2
builder.Entity<Member>(m =>
{
m.@R_10_10586@ble("Member",x.RecruitmentMemberID
});
nav.Withowner().HasForeignKey(x => x.MemberID);
nav.HasOne(x => x.Member)
.WithMany(x => x.Recruits)
.HasForeignKey(x => x.MemberID); // Change the foreign key
});
});
这次回归
var member = await _db.Members.AsnoTrack()
.Include(x => x.Recruits)
.FirstOrDefaultAsync(x => x.ID == 1,token);
// member.Recurits.Count is 2 which is correct
// member.Recurits.SELEct(x => x.Recruitment.ID) are all 1 which is incorrect
为您的课程添加关系
public partial class Member
{
public Member()
{
MemberMembers = new HashSet<MemberRecruit>();
MemberRecruits = new HashSet<MemberRecruit>();
}
[Key]
public int id { get; set; }
public String Name { get; set; }
[InverseProperty(nameof(MemberRecruit.Member))]
public virtual ICollection<MemberRecruit> MemberRecruits { get; set; }
[InverseProperty(nameof(MemberRecruit.Recruit))]
public virtual ICollection<MemberRecruit> MemberMembers { get; set; }
}
public partial class MemberRecruit
{
[Key]
public int id { get; set; }
public int RecruitId { get; set; }
public int MemberId { get; set; }
[ForeignKey(nameof(MemberId))]
[InverseProperty("MemberRecruits")]
public virtual Member Member { get; set; }
[ForeignKey(nameof(RecruitId))]
[InverseProperty("MemberMembers")]
public virtual Member Recruit { get; set; }
}
和 dbcontext
public virtual DbSet<Member> Members{ get; set; }
public virtual DbSet<MemberRecruit> MemberRecruits { get; set; }
protected override void OnModelCreaTing(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MemberRecruit>(entity =>
{
entity.HasOne(d => d.Member)
.WithMany(p => p.MemberRecruits)
.HasForeignKey(d => d.MemberId)
.ondelete(deleteBehavior.ClientSetnull);
entity.HasOne(d => d.Recruit)
.WithMany(p => p.MemberMembers)
.HasForeignKey(d => d.RecruitId);
});
由于任何成员都可能是另一个成员的新成员和另一个新成员的成员,因此它有 2 个虚拟集合 - 1 个显示他是另一个新成员的记录(在 memberId 部分),第二个显示他是另一个新成员的记录招募另一个成员(在recruitId 部分)。因此,如果您想查看会员的所有招聘人员,您可以通过两种方式进行
var recruiters=context.MemberRecruits
.Where(i=> i.MemberId==memberId)
.SELEct(i=>i.Recruit)
.ToList();
//or
var recruits = _context.Members
.Where(i => i.Id == memberId)
.SELEct(i => i.MemberRecruits.SELEct(j => j.Recruit)).FirstOrDefault();
第二个查询看起来有点奇怪,但您应该明白,members 的意思是 member 是 member,recruss - where member 是招聘人员。也许更好地重命名集合“AsMember”和“AsRecruiter”。由你决定。 由于查询 MemberRecruit 容易得多,我建议使用它进行查询。 另一个例子。 memberId 是招聘人员的成员
var members=context.MemberRecruits
.Where(i=> i.RecruitEID==memberId)
.SELEct(i=>i.Member)
.ToList();
,
如果您想使用第二个选项,根据 MS Docs Single navigation property,您可以通过使用 Fluent API 定义这样的关系来设置导航属性。
给定以下类
public class Member
{
public int id { get; set; }
public String Name { get; set; }
public IList<Member> Recruitments { get; set; }
}
protected override void OnModelCreaTing(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Member>()
.Hasmany(b => b.Member)
.WithOne();
}
给定以下类
public class Member
{
[Key]
public int id { get; set; }
public String Name { get; set; }
public IList<MemberRecruit> Recruitments { get; set; }
}
public class MemberRecruit
{
[Key]
public int id { get; set; }
public int RecruitmentMemberId { get; set; }
public Member RecruitmentMember { get; set; }
}
protected override void OnModelCreaTing(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Member>()
.Hasmany(b => b.MemberRecruit)
.WithOne();
modelBuilder.Entity<MemberRecruit>()
.HasOne(b => b.RecruitmentMember)
.WithOne();
}
你应该可以这样查询
var memeber = context.Member
.Include(x => x.Recruitments)
.FirstOrDefaultAsync(x => x.Id == request.Id);
var memberRecruitments = member.Recruitments
.SELEct(x => new Member
{
Id = x.Id,Name = x.Name
}).ToList();
,
不确定这是否是最佳做法,但以下有效
public class Member
{
public int id { get; set; }
public String Name { get; set; }
public IList<MemberRecruit> Recruits { get; set; }
}
public class MemberRecruit
{
public int MemberId { get; set; }
public int RecruitmentMemberId { get; set; }
public Member Recruitment { get; set; } // This is the recruited member
}
数据库上下文
builder.Entity<Member>(m =>
{
m.@R_10_10586@ble("Member","dbo");
m.HasKey(x => x.Id);
m.Hasmany(x => x.Recruits)
.WithOne()
.HasForeignKey(mr => mr.MemberId);
});
builder.Entity<MemberRecruit>(m =>
{
m.@R_10_10586@ble("MemberRecruit","dbo");
m.HasKey(x => new
{
x.MemberId,x.RecruitmentMemberId
});
m.HasOne(x => x.Recruitment)
.WithOne()
.HasForeignKey<Member>(x => x.Id)
.HasPrincipalKey<MemberRecruit>(x => x.RecruitmentMemberId);
});
查询和结果
var member = await _db.Members
.AsnoTracking()
.Include(x => x.Recruits)
.ThenInclude(x => x.Recruitment)
.FirstOrDefaultAsync(x => x.Id == request.Id,token);
// If request.Id == 1
// member.Recruits.Count is 2
// member.Recruits[0].Recruitment will be (2,"Steve")
// member.Recruits[1].Recruitment will be (3,"Bruce")
以上是大佬教程为你收集整理的EF Core 自身之间的关系映射 测试 1测试 2全部内容,希望文章能够帮你解决EF Core 自身之间的关系映射 测试 1测试 2所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。