【问题标题】:Filter list from database using in-memory list使用内存列表从数据库中过滤列表
【发布时间】:2016-10-12 13:33:02
【问题描述】:

我有一个通用的员工列表,使用 WCF Web 服务获取,还有一个带有费用报告的 SQL 表。我有一个包含费用报告列表的索引页面,我想在列表中显示员工姓名,但员工姓名没有存储在费用报告表中,只有员工 ID。通常,我会在员工和费用报告之间使用连接,但我发现我无法将内存数据集(员工)连接到 SQL 数据库调用(费用报告)。我收到有关原始类型的错误。

看来我唯一的选择是先获取所有员工,然后遍历费用报告以查找匹配的员工 ID,或者先获取所有费用报告并遍历它们并获取员工信息。问题是,在某些情况下,等式的每一侧可能有数千行。做任何一个都会非常低效。

所以我的问题是,我是否遗漏了什么,有没有办法有效地将内存数据集加入 SQL 数据库调用,或者是我唯一的选择来非规范化我的数据库并将信息存储在 SQL 表中?

【问题讨论】:

  • 您使用的是数据库优先方法吗?还是先有实体框架的代码?

标签: asp.net-mvc linq lambda inner-join


【解决方案1】:

如果您确实提供了一些代码来使用,这将非常容易。但是,您只需要通过 id 列表之类的东西进行查询,而不是完整的员工对象。大致如下:

var employeeIds = employees.Select(m => m.Id).ToList();
var expenses = db.Expenses.Where(m => employeeIds.Contains(m.EmployeeId));

同样,没有可使用的代码,因此您显然需要根据实际的类和属性名称对其进行调整。

【讨论】:

    【解决方案2】:

    正如您提到的那样,可能有数千条记录,所以您会有某种分页?我首先从数据库中提取记录,然后对员工列表进行查询。如果您将 .ToList() 放在 DB 的结果后面,那么它将执行获取结果并加载到内存中的 SQL。也就是说,如果您使用的是 ORM 之类的实体框架或 linq to sql。

    var itemsPage = 50;
    var expensesPage = expenses
      .Skip(itemsPage * pageNumber)
      .Take(itemsPage)
      .ToList();
    
    var result = expensesPage
      .Join(employees,
        exp => exp.EmployeeId,
        emp => emp.Id,
        (expense, employee) => new ExpenseViewModel { employee.Name, expense.Expenses }
      );
    

    如果也有数千名员工,那么我会更改为 WCF 服务以接受员工 ID 列表,该列表将返回您要求的员工列表并使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-05
      • 2014-04-28
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-26
      相关资源
      最近更新 更多