C# 重构代码,使顶层实体的行为类似于上下文

C# 重构代码,使顶层实体的行为类似于上下文,c#,sql,asp.net-mvc,entity-framework,orm,C#,Sql,Asp.net Mvc,Entity Framework,Orm,考虑以下两个实体 1 n Department -----> Student 假设有大量基于此结构的遗留代码 现在假设必须引入一个新的实体,Univeristy: 1 n 1 n Univeristy ------> Department -----> Student 然而,大学的行为必须像一个上下文而不仅仅像一个普通实体,如下所示。 每当系统用户认证自己属于Univeristy X并调用

考虑以下两个实体

           1    n
Department -----> Student
假设有大量基于此结构的遗留代码

现在假设必须引入一个新的实体,
Univeristy

           1     n            1    n
Univeristy ------> Department -----> Student
然而,
大学
的行为必须像一个上下文而不仅仅像一个普通实体,如下所示。 每当系统用户认证自己属于Univeristy X并调用其中一个遗留方法时,必须仅向属于University X(直接或间接)的实体授予访问权限。上下文将一直持续到用户注销。(这是一个web应用程序。)

例如,一条像

dbContext.Set()

遗留代码中的某个地方应该只返回那些属于X大学的学生


我有什么选择?修改遗留代码不是一个选项。

如果不知道遗留代码如何与图片相匹配,很难给您一个准确的答案,但我会试一试

根据数据库的设置方式(例如,如果学生数据库表上有大学Id),您可能只需添加学生导航属性

public class University
{
    public virtual int Id { get; set; }

    public virtual ICollection<Department> Departments { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}
公立大学
{
公共虚拟整数Id{get;set;}
公共虚拟ICollection部门{get;set;}
公共虚拟ICollection学生{get;set;}
}
如果这不起作用,您可以尝试通过以下部门访问所有学生:

public class University
{
    public virtual int Id { get; set; }

    public virtual ICollection<Department> Departments { get; set; }

    public virtual ICollection<Student> Students 
    {
        get { return Departments.SelectMany(d => d.Students); }
    }
}
公立大学
{
公共虚拟整数Id{get;set;}
公共虚拟ICollection部门{get;set;}
公共虚拟学院学生
{
获取{返回部门。选择many(d=>d.Students);}
}
}
然而,这可能效率较低

最后,您可以使用repository模式并创建一个StudentRepository,它允许您运行各种查询以获取学生

public class StudentRepository
{
      public IEnumerable<Student>  GetStudents(University university) 
      {
           return dbContext.Set<Student>().Where(s => s.Department.University.Id == university.Id);
      }
}
public class StudentRepository
{
公立学校学生(大学)
{
返回dbContext.Set(),其中(s=>s.Department.University.Id==University.Id);
}
}

我要提出的另一个建议是,不要让DbContext在用户登录的整个时间内保持不变。我将为每个web请求创建一个DbContext。搜索实体框架工作单元以了解我的意思。

如果您可以给出一个遗留代码的示例,这些代码应该保持不变,但行为仍然不同,那么这将更加清楚。