У меня проблема с запросом linq, когда я пытаюсь извлечь из него определенную информацию и просто не могу найти, где проблема.У меня есть инструменты, задачи и сущность MN ToolTask в моей базе ef core.Этот запрос включает 2 левых внешних соединения и группу в конце.
Несмотря на то, что я проверяю, являются ли сгруппированные значения не равными NULL, я все еще получаю сообщение об ошибке типа «Обнуляемый объект должен иметь значение».Что мне здесь не хватает?
Также кажется, что этот запрос 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;
}
}
}
ToolTask
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));
}
}
}
Каждый класс сущностей имеет свой собственный класс конфигурации, но в нем нет ничего огромного, кроме установки первичных ключейи режим доступа к резервным полям.