EF Core Circular Relationship Mapping - PullRequest
       26

EF Core Circular Relationship Mapping

0 голосов
/ 24 октября 2019

С учетом следующих моделей сущностей:

public class Workshop
{
    public Guid Id { get; set; }
    public string Name { get; set; }

    public ICollection<QuoteRequest> QuoteRequests { get; set; }
}

public class QuoteRequest
{
    public Guid Id { get; set; }
    public Guid CustomerId { get; set; }
    public Guid WorkshopId { get; set; }
    public bool Responded { get; set; }
    public decimal? Amount { get; set; }

    public virtual Customer Customer { get; set; }
    public virtual Workshop Workshop { get; set; }
}

и следующих 2 моделей просмотра:

public class WorkshopModel
{
    public Guid Id { get; set; }
    public string Name { get; set; }

    public ICollection<QuoteRequestModel> QuoteRequests { get; set; }
}

public class QuoteRequestModel
{
    public Guid Id { get; set; }
    public Guid CustomerId { get; set; }
    public Guid WorkshopId { get; set; }
    public bool Responded { get; set; }
    public decimal? Amount { get; set; }

    public CustomerModel Customer { get; set; }
    public WorkshopModel Workshop { get; set; }
}

Далее с учетом следующего запроса:

    public async Task<Workshop> GetWorkshopAsync(Guid id, bool includeQuotes = false)
    {
        IQueryable<Workshop> query = _context.Workshops;

        if (includeQuotes)
        {
            query = query.Include(w => w.QuoteRequests);
        }

        return await query.FirstOrDefaultAsync(w => w.Id == id);
    }

Независимо от того, что я делаю, я не могу заставить EF не давать мне круговые отношения при запросе Workshop. Например, я запрашиваю один Workshop, который имеет 14 QuoteRequests, каждый из которых имеет Workshop, каждый из которых имеет 14 QuoteRequests и т. Д. И т. Д.:

enter image description here

У меня действительно установлена ​​настройка обработки петли эталонной петли в json, но это не дает мне желаемого результата

services.AddControllers()
        .AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

Я хочу таким образом вырезать этот круг в моем отображениипрофиль. Я использую автомаппер. Мне удалось разорвать круговую ссылку с помощью моего профиля сопоставления со стороны QuoteRequest:

CreateMap<QuoteRequestModel, QuoteRequest>()
    .ForMember(dest => dest.Customer, opt => opt.MapFrom(src => src.Customer))
    .ForMember(dest => dest.Workshop, opt => opt.MapFrom(src => src.Workshop))
    .ForPath(dest => dest.Customer.QuoteRequests, opt => opt.MapFrom(src => new List<QuoteRequest>()))
    .ForPath(dest => dest.Workshop.QuoteRequests, opt => opt.MapFrom(src => new List<QuoteRequest>()));

CreateMap<QuoteRequest, QuoteRequestModel>()
    .ForMember(dest => dest.Customer, opt => opt.MapFrom(src => src.Customer))
    .ForMember(dest => dest.Workshop, opt => opt.MapFrom(src => src.Workshop))
    .ForPath(dest => dest.Customer.QuoteRequests, opt => opt.MapFrom(src => new List<QuoteRequestModel>()))
    .ForPath(dest => dest.Workshop.QuoteRequests, opt => opt.MapFrom(src => new List<QuoteRequestModel>()));

Это может быть немного нестабильным решением, но сейчас оно работает, когда я запрашиваю отдельное лицо QuoteRequest. Я хочу выяснить, как сделать то же самое в профиле отображения со стороны Workshop:

CreateMap<WorkshopModel, Workshop>()
    .ForMember(dest => dest.QuoteRequests, opt => opt.MapFrom(src => src.QuoteRequests));

CreateMap<Workshop, WorkshopModel>()
    .ForMember(dest => dest.QuoteRequests, opt => opt.MapFrom(src => src.QuoteRequests));

Я не могу нацелить каждую итерацию QuoteRequests, чтобы установить Workshop значение по умолчанию.

1 Ответ

1 голос
/ 24 октября 2019

Это не проблема. То, что вы видите, это исправление объекта EF. Поскольку эти объекты уже есть в кеше объектов, он автоматически «исправляет» отношения на каждом объекте, не запрашивая что-либо снова.

Единственный раз, когда это может быть проблемой, - во время сериализации, поскольку сериализация будет пытатьсярекурсивно детализировать до бесконечности. Однако, в зависимости от метода сериализации, существуют разные способы предотвращения такой рекурсивной сериализации. Кроме того, вы не должны сериализовать сущности напрямую, в любом случае. Вместо этого вы должны отобразить их в классы DTO, где вы затем определите более базовую структуру, которая не будет страдать от тех же самых рекурсивных проблем. Затем вы должны сериализовать DTO, а не сущность.

...