c# – 具有存储库模式的实体框架插入多对多
发布时间:2020-12-15 22:16:12 所属栏目:百科 来源:网络整理
导读:我继承了一个使用Entity Framework和Repository Pattern的解决方案. 在这个解决方案中,以前的开发人员忘记实现多对多关系,所以现在我必须这样做. 我不太熟悉EF或模式??,所以我无法得到我想要实现的工作,即插入多对多关系. 我可以让EF在数据库中创建关系表,但
我继承了一个使用Entity Framework和Repository Pattern的解决方案.
在这个解决方案中,以前的开发人员忘记实现多对多关系,所以现在我必须这样做. 我不太熟悉EF或模式??,所以我无法得到我想要实现的工作,即插入多对多关系. 我见过other questions similar to this one,但是没有一个与这里的模式实现完全匹配,然后我对一切都不熟悉,无法绕过它. 有人可以看看代码,看看我错过了什么? (代码已经简化了一点,这不是实际的学生/课程项目,但我使用的是这些名称,因为它们已在之前的例子中使用过) 这是我的代码.非常简化,没有数千个接口. 实体类 public class Student { // This class already existed public int StudentId { get; protected set; } public virtual ICollection<Course> Courses { get; set; } // I added this property } public class Course { // This class already existed public int CourseId { get; protected set; } public virtual ICollection<Student> Students { get; set; } // I added this property } 知识库 public class StudentRepository { protected DbContext DbContext { get; private set; } protected DbSet<Student> DbSet { get; private set; } public StudentRepository(DbContext dbContext) { DbContext = dbContext; DbSet = dbContext.Set<Student>(); } public virtual void AddOrUpdate(Student entity) { if (Exists(entity)) { Update(entity); } else { Add(entity); } } public virtual void Update(Student entity) { var dbEntityEntry = DbContext.Entry(entity); if (dbEntityEntry.State == EntityState.Detached) { DbSet.Attach(entity); } dbEntityEntry.State = EntityState.Modified; } public virtual Student Add(Student entity) { var dbEntityEntry = DbContext.Entry(entity); if (dbEntityEntry.State != EntityState.Detached) { dbEntityEntry.State = EntityState.Added; } else { return DbSet.Add(entity); } return null; } public IQueryable<Student> Queryable() { return DbSet; } public bool Exists(Student entity) { var objContext = ((IObjectContextAdapter)DbContext).ObjectContext; object existingEntity; var exists = objContext.TryGetObjectByKey(GetEntityKey(entity),out existingEntity); if (exists) objContext.Detach(existingEntity); return exists; } private EntityKey GetEntityKey(Student entity) { var objContext = ((IObjectContextAdapter)DbContext).ObjectContext; var objSet = objContext.CreateObjectSet<T>(); var entityKey = objContext.CreateEntityKey(objSet.EntitySet.Name,entity); return entityKey; } } 工作单位 public class StudentUow : UnitOfWork<MyDbContext> { public StudentRepository Students { get { return CreateRepository<StudentRepository>(); } } public CourseRepository Courses { get { return CreateRepository<CourseRepository>(); } } } public class UnitOfWork<TContext> where TContext : System.Data.Entity.DbContext { private readonly TContext _dbContext; private IRepositoryProvider _repositoryProvider; protected UnitOfWork(IRepositoryProvider provider) { _repositoryProvider = provider; } protected TRepository CreateRepository<TRepository>() { return _repositoryProvider.Create<TRepository>(_dbContext,"default"); } public void Commit() { _dbContext.SaveChanges(); } } [Export(typeof(IUnitOfWorkProvider))] [PartCreationPolicy(CreationPolicy.Shared)] public class UnitOfWorkProvider { [Import] private IRepositoryProvider _repositoryProvider; public StudentUow GetStudentUow() { return new StudentUow(_repositoryProvider); } } [Export(typeof(IRepositoryProvider))] public class MyRepositoryProvider { public MyRepositoryProvider() { Register<RepositoryFactory<IProductRepository,StudentRepository>>(); } public TRepository Create<TRepository>(DbContext dbContext,string conntextKey) { var type = typeof (TRepository); if (!_factories.ContainsKey(type)) throw new UnknownFactoryException(type); return (TRepository)_factories[type].Create(dbContext); } public void Register<TRepositoryFactory>() where TRepositoryFactory : IRepositoryFactory,new() { var factory = new TRepositoryFactory(); if (_factories.ContainsKey(factory.Type)) throw new FactoryTypeAlreadyRegisteredException(factory.Type); _factories[factory.Type] = factory; } } “主要”课程 public class MyClass { public AddCourse(int studentId,List<int> courses) { using (var studentUow = new StudentUow()) { foreach (int courseId in courses) { Student s = studentUow.Student.Queryable().First(x => x.StudentId == studentId); Course c = studentUow.Course.Queryable().First(x => x.CourseId == courseId); s.Courses.Add(c); studentUow.Student.AddOrUpdate(s); } studentUow.Commit(); } } } 如果您遗漏了某些功能,请发表评论,然后我会添加它,或者让您知道它在哪里. 解决方法
默认情况下,EF不在查询中包含相关实体.为此,您需要在需要时手动包含课程.还有一个问题是,在每次迭代中,您一次又一次地取回学生,因此课程集合丢失了.这应该工作:
using System.Data.Entity; ... using (var studentUow = new StudentUow()) { Student s = studentUow.Student.Queryable().Include(x => x.Courses).First(x => x.StudentId == studentId); foreach (int courseId in courses) { Course c = studentUow.Course.Queryable().First(x => x.CourseId == courseId); s.Courses.Add(c); c.Students.Add(s); studentUow.Course.Update(c); } studentUow.Student.Update(s); studentUow.Commit(); } 如果可能的话,我强烈建议您重构代码. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
热点阅读