如何使用通用存储库模式的连接 – 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()
,它就会在数据库中运行。 请注意,您必须将相同的上下文传递给两个存储库才能使其正常工作。
我建议您查看工作单元设计模式。 处理多个存储库时,它会有很大帮助。
当涉及多个实体集时,这是一种更有条理且更易于维护的处理事务的方式,并促进更好地分离关注点。
希望我能正确理解你的问题,这有帮助。