通过外键访问对象c#

时间:2016-03-06 19:51:00

标签: c# linq ef-code-first foreign-keys

我有以下代码,并想知道是否有一种方法可以重构以删除重复的逻辑。

这会导致当前用户急切加载。

  var currentEmployee = RosterContext.Employees
                    .Where(e => e.User.Id == id)
                    .Include(e => e.Job.Department).FirstOrDefault();

var job = RosterContext.Employees.Where(e=>e.Job.Department.Id == currentEmployee.Job.DepartmentId).ToList();

我创建了另一个相同的上下文,用于比较第一行代码,以生成在同一部门工作的所有员工姓名。我的问题是,因为我使用两个使用相同上下文(Employees)的linq表达式,我能将两个linq查询合并为一个吗? 它可能会成为一个很长的linq表达式,但它应该用于获取当前用户对象,然后比较用户对象以获得共享相同部门ID的所有员工?

3 个答案:

答案 0 :(得分:0)

尝试ORM框架是有意义的,例如Entity Framework或NHibernate。 ORM framewok将数据库FK关系建模为一侧的标量属性和关系另一侧的矢量属性(集合)。 例如,Department将拥有一个集合属性Jobs,而一个Job实体将具有一个标量Department属性。 例如,在FK上使用联接的数据库查询变成了依赖项属性导航 - 要访问当前部门中的员工列表,您只需返回类似employee.Department.Employees的内容 - 也就是说,假设您的实体都已加载(这相当简单)在EF中实现,使用include语句)

答案 1 :(得分:0)

EF Code First支持开箱即用的关系。您可以使用约定或显式指定关系(例如,如果外键属性被命名为奇怪的东西)。例如:https://msdn.microsoft.com/en-us/data/hh134698.aspx

当你正确配置你的模型时,你应该可以访问这样的部门:

var currentUser = _unitOfWork.Employee.GetEmployeeByID(loggedInUser.GetUser(user).Id);
var job = currentUser.Job;
var department = job.Department;

// or

var department = _unitOfWork.Employee.GetEmployeeByID(loggedInUser.GetUser(user).Id).Job.Department;

显示在同一部门工作的所有员工:

var coworkers = department.Jobs.SelectMany(j => j.Employees);

<强>更新

使用单个存储库类的预先加载(在此实例中不需要多个存储库类,因此不需要使用工作单元):

public class EmployeeRepository {
    private readonly MyContext _context = new MyContext(); // Or whatever...

    public IList<Employee> GetCoworkers(int userId) {
        var currentEmployee = _context.Employees
            .Where(e => e.UserId == userId)
            .Include(e => e.Job.Department)     // Use eager loading; this will fetch Job and Department rows for this user
            .FirstOrDefault();

        var department = currentEmployee.Job.Department;
        var coworkers = department.Jobs.SelectMany(j => j.Employees);
        return coworkers;
    }
}

并称之为......

var repo = new EmployeeRepository();
var coworkers = repo.GetCoworkers(loggedInUser.GetUser(user).Id);

通过选择当前用户的工作和部门(就像我已经完成的那样),然后通过相反的工作和员工返回时,您可能能够使存储库查询更有效率。我会把它留给你。

答案 2 :(得分:0)

在Entity Framework中,您可以使用using子句来附加子项。例如,在纯EF中你可以做到:

var department = context.Department.Include(d => d.Jobs).First(d => d.DepartmentId == departmentId);

https://msdn.microsoft.com/en-us/library/gg671236%28v=vs.103%29.aspx#Anchor_1

使用存储库,您可能需要执行以下操作:

EF Including Other Entities (Generic Repository pattern)