我有一个 linq 查询问题,我试图从中获取某些信息,但根本找不到问题所在。我的 ef 核心数据库中有工具、任务和 MN ToolTask 实体。此查询包括 2 个左外连接和最后的 group by。
即使我正在检查分组值是否不为空,我仍然会收到一条错误消息,例如“可为空的对象必须有一个值”。我在这里想念什么?
此外,似乎这个 linq 查询是在客户端评估的,我能做些什么来使其成为服务器端?当我由于某种原因在代码中没有“let maxDateV ...”行时,它一直是服务器端。
var max = (from t in _fabContext.Tools
join tt in _fabContext.ToolTask on t.ToolId equals tt.ToolId into tt1
from tt in tt1.DefaultIfEmpty()
join ts in _fabContext.Tasks on tt.TaskId equals ts.TaskId into ts1
from ts in ts1.DefaultIfEmpty()
group tt by tt.ToolId into g
let maxOrderV = g.Max(c => c != null ? c.Order : 0)
let maxDateV = g.Max(c => c != null ? c.Task.ExportDate : DateTime.MinValue)
select new
{
ToolId = g.Key,
MaxOrder = maxOrderV,
MaxExportDate = maxDateV
}).ToDictionary(d => d.ToolId, d =>
new OrderExportDate {
Order = d.MaxOrder,
ExportDate = d.MaxExportDate
});
更新 1(实体类):
任务
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace Main.DataLayer.EfClasses
{
public class Task
{
public int TaskId { get; private set; }
[Required]
public string Name { get; private set; }
[Required]
public int ProfileId { get; private set; }
[Required]
public DateTime ExportDate { get; private set; }
private HashSet<ToolTask> _toolTask;
public IEnumerable<ToolTask> ToolTask => _toolTask?.ToList();
private Task()
{
}
public Task(
string name,
int profileId,
DateTime exportDate)
{
Name = name;
ProfileId = profileId;
ExportDate = exportDate;
}
}
}
工具任务
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace Main.DataLayer.EfClasses
{
public class ToolTask
{
public int ToolId
{
get; private set;
}
public Tool Tool
{
get; private set;
}
public int TaskId
{
get; private set;
}
public Task Task
{
get; private set;
}
[Required]
public int SortOrder
{
get; private set;
}
private ToolTask() { }
internal ToolTask(Tool tool, Task task, int sortOrder)
{
Tool = tool;
ToolId = tool.ToolId;
Task = task;
TaskId = task.TaskId;
SortOrder = sortOrder;
}
public void ChangeOrder(int order)
{
SortOrder = order;
}
}
}
工具
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Main.DataLayer.EfCode;
namespace Main.DataLayer.EfClasses
{
public class Tool
{
public int ToolId
{
get; private set;
}
[Required]
public string Name
{
get; private set;
}
[Required]
public string Model
{
get; private set;
}
private HashSet<ToolTask> _toolTask;
public IEnumerable<ToolTask> ToolTask => _toolTask?.ToList();
internal Tool() { }
public Tool(string name, string model)
{
Name = name;
Model = model;
_toolTask = new HashSet<ToolTask>();
}
public void AddTask(Task task, int sortOrder)
{
_toolTask?.Add(new ToolTask(this, task, sortOrder));
}
}
}
每个实体类都有自己的配置类,但除了设置主键和支持字段的访问模式之外,没有什么大不了的。