如何使用通用存储库模式的连接 – entity framework

我有一个像下面的Generic Repository来处理我的CRUD ,对于一个易于使用的单个实体,当我尝试加入我的POCOs

假设我有这些POCO,它们使用流畅的api(多对多和一对多关系)进行映射:

 public class Student { public Student() { this.Courses = new HashSet(); } public int StudentId { get; set; } public string StudentName { get; set; } //FKs public virtual Standard Standard { get; set; } public int StdandardRefId { get; set; } public virtual ICollection Courses { get; set; } } public class Course { public Course() { this.Students = new HashSet(); } public int CourseId { get; set; } public string CourseName { get; set; } public virtual ICollection Students { get; set; } } public class Standard { public Standard() { Students = new List(); } public int StandardId { get; set; } public string Description { get; set; } public virtual ICollection Students { get; set; } } 

制图:

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Many-To-Many modelBuilder.Entity() .HasMany(s => s.Courses) .WithMany(c => c.Students) .Map(cs => { cs.MapLeftKey("StudentRefId"); cs.MapRightKey("CourseRefId"); cs.ToTable("StudentCourse"); }); //One-To-Many modelBuilder.Entity() .HasRequired(s => s.Standard) .WithMany(s => s.Students) .HasForeignKey(s => s.StandardId); } 

通用存储库:

 public class Repository : IRepository where T : class, IDisposable { internal MyDbContext context; internal DbSet dbSet; public Repository() { context = new MyDbContext(); this.dbSet = context.Set(); } public bool Add(T entity) { var query = dbSet.Add(entity); if (query != null) return true; return false; } public bool Update(T entity) { dbSet.Attach(entity); var query = context.Entry(entity).State = EntityState.Modified; if (query == EntityState.Modified) return true; return false; } public bool Delete(T entity) { var query = dbSet.Remove(entity); if (query != null) return true; return false; } public bool Delete(Guid id) { var query = dbSet.Remove(dbSet.Find(id)); if (query != null) return true; return false; } public T GetById(Guid id) { var query = dbSet.Find(id); if (query != null) return query; else return null; } public ICollection GetAll() { return dbSet.AsEnumerable().ToList(); } public void Save() { context.SaveChanges(); } public void Dispose() { if (context != null) { context.Dispose(); context = null; } } } 

现在,如果我想加入Standard to Many-to-Many Table,我怎么能这样做?

所以根据你的编辑,我假设你想加入学生和标准。

您要做的第一件事是更改存储库,以便它不实例化上下文。 您应该将其作为参数传递并存储对它的引用:

 public Repository(MyDbContext myCtx) { context = myCtx; this.dbSet = context.Set(); } 

您要做的第二件事是更改存储库以更改GetAll()方法以返回IQueryable而不是ICollection

然后更改GetAll()的实现:

 return dbSet; 

这样您只能获得查询而不是所有实体的评估列表。 然后,您可以使用存储库的GetAll()方法进行连接,就像使用数据库集一样:

 using (MyDbContext ctx = new MyDbContext()) { var studentRep = new Repository(ctx); var standardRep = new Repository(ctx); var studentToStandard = studentRep.GetAll().Join(standardRep.GetAll(), student => student.StandardRefId, standard => standard.StandardId, (stud, stand) => new { Student=stud, Standard=stand }).ToList(); } 

通过这个,你可以在studentToStandard获得一个IQueryable ,一旦你调用ToList() ,它就会在数据库中运行。 请注意,您必须将相同的上下文传递给两个存储库才能使其正常工作。

我建议您查看工作单元设计模式。 处理多个存储库时,它会有很大帮助。

https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-的工作图案,在安-ASP净MVC应用程序

当涉及多个实体集时,这是一种更有条理且更易于维护的处理事务的方式,并促进更好地分离关注点。

希望我能正确理解你的问题,这有帮助。