Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有存储库模式的实体框架插入多对多_C#_.net_Entity Framework_Repository Pattern - Fatal编程技术网

C# 具有存储库模式的实体框架插入多对多

C# 具有存储库模式的实体框架插入多对多,c#,.net,entity-framework,repository-pattern,C#,.net,Entity Framework,Repository Pattern,我继承了一个使用实体框架和存储库模式的解决方案。 在这个解决方案中,以前的开发人员忘记了实现多对多关系,所以现在我不得不这样做 我对EF或模式都不太熟悉,所以我无法将我试图实现的目标付诸实际,也就是插入到多对多关系中。 我可以让EF在数据库中创建关系表,但不知怎的,我无法插入其中 我已经看到了,但是没有一个与模式在这里的实现方式完全匹配,而且我对每件事都不熟悉,所以我无法理解它 有人能看一下代码,看看我遗漏了什么吗?(代码已经简化了一点,这不是实际的学生/课程项目,但我使用的名称与前面示例中使用

我继承了一个使用实体框架和存储库模式的解决方案。 在这个解决方案中,以前的开发人员忘记了实现多对多关系,所以现在我不得不这样做

我对EF或模式都不太熟悉,所以我无法将我试图实现的目标付诸实际,也就是插入到多对多关系中。 我可以让EF在数据库中创建关系表,但不知怎的,我无法插入其中

我已经看到了,但是没有一个与模式在这里的实现方式完全匹配,而且我对每件事都不熟悉,所以我无法理解它

有人能看一下代码,看看我遗漏了什么吗?(代码已经简化了一点,这不是实际的学生/课程项目,但我使用的名称与前面示例中使用的名称相同)

这是我的密码。非常简单,没有数千个接口。 这运行得很好,没有例外。 在“Main”类中调试并快速查看
studentUow
时,Students.Courses集合确实包含一个值,但从未保存到数据库中。而且,它只包含一个值,即使它应该包含多个课程

实体类
公共类学生{//该类已存在
public int StudentId{get;protected set;}
公共虚拟ICollection课程{get;set;}//我添加了此属性
}
公共类课程{//此类已存在
public int CourseId{get;protected set;}
公共虚拟ICollection学生{get;set;}//我添加了此属性
}
存储库
public class StudentRepository{
受保护的DbContext DbContext{get;private set;}
受保护的DbSet DbSet{get;private set;}
公共研究职位(DbContext DbContext){
DbContext=DbContext;
DbSet=dbContext.Set();
}
公共虚拟void AddOrUpdate(学生实体){
如果(存在(实体)){
更新(实体);
}否则{
添加(实体);
}
}
公共虚拟无效更新(学生实体){
var dbEntityEntry=DbContext.Entry(实体);
if(dbEntityEntry.State==EntityState.Distached){
附加数据集(实体);
}
dbEntityEntry.State=EntityState.Modified;
}
公共虚拟学生添加(学生实体){
var dbEntityEntry=DbContext.Entry(实体);
if(dbEntityEntry.State!=EntityState.Distached){
dbEntityEntry.State=EntityState.Added;
}否则{
返回DbSet.Add(实体);
}
返回null;
}
公共IQueryable可查询(){
返回DbSet;
}
存在公共bool(学生实体){
var objContext=((IObjectContextAdapter)DbContext).ObjectContext;
对象存在实体;
var exists=objContext.TryGetObjectByKey(GetEntityKey(实体),out existingEntity);
如果(存在)objContext.Detach(存在实体);
回报存在;
}
私有EntityKey GetEntityKey(学生实体){
var objContext=((IObjectContextAdapter)DbContext).ObjectContext;
var objSet=objContext.CreateObjectSet();
var entityKey=objContext.CreateEntityKey(objSet.EntitySet.Name,entity);
返回entityKey;
}
}
工作单位
公共班级学生UOW:UnitOfWork{
public StudentRepository学生{get{return CreateRepository();}}
公共课程定位课程{get{return CreateRepository();}}
}
公共类UnitOfWork,其中TContext:System.Data.Entity.DbContext{
私有只读TContext_dbContext;
私人IRepositoryProvider\u repositoryProvider;
受保护的工作单元(IRepositoryProvider){
_repositoryProvider=提供者;
}
受保护的TRepository CreateRepository(){
返回_repositoryProvider.Create(_dbContext,“default”);
}
公共无效提交(){
_dbContext.SaveChanges();
}
}
[导出(类型为(IUnitOfWorkProvider))]
[PartCreationPolicy(CreationPolicy.Shared)]
公共类UnitOfWorkProvider{
[导入]私有IRepositoryProvider\u repositoryProvider;
公共学生UOW GetStudentUow(){
返回新学生UOW(_repositoryProvider);
}
}
[导出(类型(IRepositoryProvider))]
公共类MyRepositoryProvider{
公共MyRepositoryProvider(){
寄存器();
}
公共TRepository创建(DbContext DbContext,string conntextKey)
{
var类型=类型(TRepository);
如果(!\u工厂。容器(类型))
抛出新的UnknownFactoryException(类型);
return(TRepository)_factories[type].Create(dbContext);
}
public void Register(),其中TRepositoryFactory:IRepositoryFactory,new()
{
var factory=new TRepositoryFactory();
如果(_factories.ContainsKey(factory.Type))抛出新的FactoryTypeAlreadyRegisteredException(factory.Type);
_工厂[工厂.类型]=工厂;
}
}
“主要”类
公共类MyClass{
公共课程(国际学生ID,列出课程){
使用(var studentUow=new studentUow()){
foreach(课程中的int课程ID){
Student s=studentUow.Student.Queryable().First(x=>x.StudentId==StudentId);
课程c=studentUow.Course.Queryable().First(x=>x.CourseId==CourseId);
s、 加入(c);
studentUow.Student.addor更新;
}
studentUow.Commit();
}
}
}

如果您缺少一些功能,请留下评论,我会添加它,或者让您知道它在哪里。

EF默认情况下不在查询中包含相关实体。为了做到这一点,您需要在需要时手动包括课程。还有一个问题是,在每一次迭代中,您都会一次又一次地吸引学生,因此课程的收集是很困难的
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();
        }
    }
}
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();
}