使用多对多关系efcore的正确方法

问题描述 投票:0回答:1

现在我有2个具有多对多关系的表。

旅程有很多地址,但是同一个地址可以有很多旅程。

这是我正在使用的类:

地址类别:

public class Address
{
    [Key]
    public int id { get; set; }
    [Required]
    public string name { get; set; }
    [JsonIgnore]
    public virtual ICollection<JourneyAddress> JourneyAddress { get; set; }

}

旅程舱:

public class Journey
{
    [Key]
    public int id { get; set; }
    public virtual ICollection<JourneyAddress> journeyAddress { get; set; }
    [ForeignKey("vehicleId")]
    public Vehicle vehicle { get; set; }
    public int vehicleId { get; set; }
    [ForeignKey("driverId")]
    public Driver driver { get; set; }
    public int driverId { get; set; }
    public DateTime date { get; set; }
    public string measureUnit { get; set; }
    public float quantity { get; set; }
    public float valueForUnit { get; set; }
    public float timeStop { get; set; }
    public float valueStopTime { get; set; }
    public string customer { get; set; }
}

JourneyAddress类:

public class JourneyAddress
{
    public int journeyId { get; set; }
    public Journey journey { get; set; }
    public int addressId { get; set; }
    public Address address { get; set; }
}

这是上下文:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<JourneyAddress>()
            .HasKey(bc => new { bc.journeyId, bc.addressId });
        modelBuilder.Entity<JourneyAddress>()
            .HasOne(bc => bc.journey)
            .WithMany(b => b.journeyAddress)
            .HasForeignKey(bc => bc.journeyId)
            .OnDelete(DeleteBehavior.Cascade);
        modelBuilder.Entity<JourneyAddress>()
            .HasOne(bc => bc.address)
            .WithMany(c => c.JourneyAddress)
            .HasForeignKey(bc => bc.addressId)
            .OnDelete(DeleteBehavior.Cascade);
        modelBuilder.Entity<Journey>()
            .HasOne(c => c.vehicle)
            .WithMany(e => e.Journeys)
            .HasForeignKey(c => c.vehicleId)
            .OnDelete(DeleteBehavior.Cascade);
        modelBuilder.Entity<Journey>()
            .HasOne(c => c.driver)
            .WithMany(e => e.Journeys)
            .HasForeignKey(c => c.driverId)
            .OnDelete(DeleteBehavior.Cascade);
    }

这是JourneyController,我应该在其中加载所有信息:

    [HttpGet]
    public async Task<ActionResult<IEnumerable<Journey>>> GetJourneys()
    {
        return await _context.Journey.Include(p => p.vehicle).Include(p => p.driver).Include(p => p.journeyAddress).ThenInclude(p => p.address).ToListAsync();
    }

但是当我尝试在我的api上使用Postman检索所有信息时,会收到此错误:

System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHanlding.Preserve on JsonSerializerOptions to support cycles.
   at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected(Int32 maxDepth)
   at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
c# entity-framework-core
1个回答
0
投票

我认为仅对Journey和Address类进行关系配置就足够了-将关系设置为JourneyAddress。

© www.soinside.com 2019 - 2024. All rights reserved.