Простой ответ: «Не отправляйте объекты клиенту, используйте модель представления».
Если все, о чем заботится ваш клиент, - это Job и список его тегов:
[Serializable]
public class JobViewModel
{
public int JobId { get; set;}
public string Title { get; set; }
public List<TagViewModel> Tags { get; set; } = new List<TagViewModel>();
}
[Serializable]
public class TagViewModel
{
public int TagId { get; set; }
public string Title { get; set; }
}
Затем выберите все вакансии и их теги: (в идеале это должен быть пункт Where или разбиение на страницы, но ради примера)
var jobs = context.Jobs.Select(j => new JobViewModel
{
JobId = j.JobId,
Title = j.Title,
Tags = j.Tags.Select(t => new TagViewModel
{
TagId = t.TagId,
Title = t.Title
}).ToList()
}).ToList();
Вы можете избежать этого ручного приведения, используя AutoMapper и его метод ProjectTo<T>
, который прекрасно интегрируется с методами IQueryable
EF.
var jobs = context.Jobs
.ProjectTo<JobViewModel>()
.ToList();
Почему?
- Избегать проблем с циклической сериализацией ссылок.
- Оптимизация запросов, отправляемых в базу данных, для получения только необходимых полей.
- Сокращение использования памяти на серверах и клиенте.
- Уменьшите объем данных, передаваемых по проводам между серверами и клиенту.
- Избегайте отправки клиенту большего количества данных, чем необходимо.(в противном случае не показана модель всего домена)
- Избегайте риска получения объектов от клиента, присоединения и сохранения изменений, которые не были предназначены.(отладчик изменяет поля или связанные объекты вручную)