我正在尝试确定一种在IQueryable
, 中使用 Linq的方法,以根据一系列值将实体“扩展”为多个查询结果。具体来说,在开始日期和结束日期之间每天扩展结果,包括。
以下是关注的实体(为了清楚起见,它们已被精简并删除了注释):
public class Location {
public int Id { get; set; }
public string Name { get; set; }
}
public class WorkAssignment {
public int Id { get; set; }
public string Name { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public virtual Location Location { get; set; }
public int LocationId { get; set; }
}
例如,假设我们有:
地点:
Id Name
1 Habitat
2 Church
工作分配:
Id Name Start End LocationId
1 Jim 29-Apr-2019 3-May-2019 1
2 Natasha 4-May-2019 7-May-2019 2
3 Jennifer 5-May-2019 6-May-2019 2
我想使用 Linq 获得以下内容,最好使用流畅的界面方法。在查询中执行“扩展”很重要(让 DB 负责)。完整的数据集和引用的实体很大,我不希望实现 using.ToList()
和foreach
语句。
WorkerName Date LocationId LocationName
Jim 29-Apr-2019 1 Habitat
Jim 30-Apr-2019 1 Habitat
Jim 1-May-2019 1 Habitat
Jim 2-May-2019 1 Habitat
Jim 3-May-2019 1 Habitat
Natasha 4-May-2019 2 Church
Natasha 5-May-2019 2 Church
Natasha 6-May-2019 2 Church
Natasha 7-May-2019 2 Church
Jennifer 5-May-2019 2 Church
Jennifer 6-May-2019 2 Church
最终目标是获得上述“扩展”,以便按位置分组(按位置名称排序),然后按日期分组(按升序排序),然后按名称为工作人员提供签到表。签到表按位置分组,然后按日期分组。每张表都会列出特定日期特定地点的工人。
我已经弄清楚了分组查询(感谢 Jon Skeet 和他所有出色的 SO 答案)。我只需要有关上述扩展的帮助,如果甚至可以在IQueryable
.
一种解决方案是结合使用日历或日期维度表(https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/)以代表您的日期范围以返回代表该范围内每个日期的实体。
例如:
public class WorkAssignment {
public int Id { get; set; }
public string Name { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public virtual Location Location { get; set; }
public int LocationId { get; set; }
}
[Table("vwWorkAssignmentByDate")]
public class WorkAssignmentDate
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public virtual Location Location { get; set; }
public int LocationId { get; set; }
public DateTime Date { get; set; }
}
请注意,WorkAssignmentDate 不会扩展 WorkAssignment。这样做的原因是,如果您扩展它,当直接查询 WorkAssignment 时,EF 将尝试 NOT IN 反对视图,这既是性能接收器,也可能在尝试加载单行时导致问题。(可能有某种形式的映射可以避免这种行为)您可以将 Id 设置为基于视图的实体的 PK 以使 EF 满意,但它不会是唯一的行标识符。(所以没有更新!不是问题,因为无论如何这是从视图中获取的)
其中 vwWorkAssignment 是将 WorkAssignment 连接到 DateDimension 表的视图:
SELECT wa.*, dd.Date
FROM dbo.WorkAssignment wa
INNER JOIN dbo.DateDimension dd
ON dd.Date >= wa.StartDate AND dd.Date <= wa.EndDate
WorkAssignmentDate 实体需要被视为只读实体。要更新工作分配,您将按 ID 加载和使用 WorkAssignment 实体。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句