Val*_*rie 1 c# entity-framework unit-of-work repository-pattern
我有一个Generic Repository像下面的处理我的CRUD,对于一个单一的实体它易于使用,问题开始时,我尝试加入我的POCOs.
假设我有这些POCO,它们使用流畅的api(多对多和一对多关系)进行映射:
public class Student
{
public Student()
{
this.Courses = new HashSet<Course>();
}
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<Course> Courses { get; set; }
}
public class Course
{
public Course()
{
this.Students = new HashSet<Student>();
}
public int CourseId { get; set; }
public string CourseName { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
public class Standard
{
public Standard()
{
Students = new List<Student>();
}
public int StandardId { get; set; }
public string Description { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
制图:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Many-To-Many
modelBuilder.Entity<Student>()
.HasMany<Course>(s => s.Courses)
.WithMany(c => c.Students)
.Map(cs =>
{
cs.MapLeftKey("StudentRefId");
cs.MapRightKey("CourseRefId");
cs.ToTable("StudentCourse");
});
//One-To-Many
modelBuilder.Entity<Student>()
.HasRequired<Standard>(s => s.Standard)
.WithMany(s => s.Students)
.HasForeignKey(s => s.StandardId);
}
Run Code Online (Sandbox Code Playgroud)
通用存储库:
public class Repository<T> : IRepository<T>
where T : class, IDisposable
{
internal MyDbContext context;
internal DbSet<T> dbSet;
public Repository()
{
context = new MyDbContext();
this.dbSet = context.Set<T>();
}
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<T> GetAll()
{
return dbSet.AsEnumerable<T>().ToList();
}
public void Save()
{
context.SaveChanges();
}
public void Dispose()
{
if (context != null)
{
context.Dispose();
context = null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我想加入Standard to Many-to-Many Table,我怎么能够做到这一点?
Ako*_*agy 15
因此,基于您的编辑,我假设您想加入学生和标准.
您要做的第一件事是更改存储库,以便它不会实例化上下文.您应该将其作为参数传递并存储对它的引用:
public Repository(MyDbContext myCtx)
{
context = myCtx;
this.dbSet = context.Set<T>();
}
Run Code Online (Sandbox Code Playgroud)
您要做的第二件事是更改您的存储库以将GetAll()方法更改为返回IQueryable<T>而不是ICollection<T>.
然后改变执行GetAll():
return dbSet;
Run Code Online (Sandbox Code Playgroud)
这样您只能获得查询而不是所有实体的评估列表.然后你就可以GetAll()像使用数据库集一样使用存储库的方法进行连接:
using (MyDbContext ctx = new MyDbContext())
{
var studentRep = new Repository<Student>(ctx);
var standardRep = new Repository<Standard>(ctx);
var studentToStandard = studentRep.GetAll().Join(standardRep.GetAll(),
student => student.StandardRefId,
standard => standard.StandardId,
(stud, stand) => new { Student=stud, Standard=stand }).ToList();
}
Run Code Online (Sandbox Code Playgroud)
有了这个,你就会得到一个IQueryable<T>in studentToStandard,一旦你调用它就会在数据库中运行ToList().请注意,您必须将相同的上下文传递给两个存储库才能使其正常工作.
我建议您查看工作单元设计模式.处理多个存储库时,它会有很大帮助.
当涉及多个实体集时,这是一种更有条理且更易于维护的处理事务的方式,并促进更好地分离关注点.
希望我能正确理解你的问题,这有帮助.
| 归档时间: |
|
| 查看次数: |
15762 次 |
| 最近记录: |