Home > Mobile >  Entity Framework Core: Owned type that has navigation properties
Entity Framework Core: Owned type that has navigation properties

Time:03-12

I have some classes:

public class Project 
{
     public TimeLine TimeLine { get; set; };
}

public class TimeLine 
{
     public ICollection<TimeLinePhases> TimeLinePhases { get; set; };
}

public TimeLinePhase 
{
}

The class Project owns TimeLine and this all works fine until I specify the navigation between TimeLine and TimeLinePhase.

Fluent API code that specifies TimeLine is owned:

  builder.Owned<TimeLine>();
  builder.entity<Project>().OwnsOne(p => p.TimeLine);

I get this error:

InvalidOperationException: Unable to determine the relationship represented by navigation 'TimeLine.TimeLinePhase' of type 'ICollection'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

So then I specify the relation between TimeLine and TimeLinePhase like this:

builder
        .Entity<TimeLine>()
        .HasMany(t => t.TimeLinePhase)
        .WithOne()
        .IsRequired(false);

But now I get this error:

The entity type 'TimeLine' cannot be configured as non-owned because it has already been configured as a owned. Use the nested builder in OwnsOne or OwnsMany on the owner entity type builder to further configure this type

How can I have TimeLine as an owned type, and still have the relation between TimeLine and TimeLinePhases?

CodePudding user response:

I brief search revealed an answer. It seems configuring an owned type having a collection is not allowed. The problem being an owned type cannot act as a principal entity for the collection

See comments by AjVickers at this GitHub page: https://github.com/dotnet/efcore/issues/27175

It seems a redesigned datastructure is needed.

CodePudding user response:

try to create relations explicitly

public class TimeLine 
{
    [InverseProperty(nameof(TimeLinePhase.TimeLine))]
     public ICollection<TimeLinePhases>? TimeLinePhases { get; set; };
}

public TimeLinePhase 
{
   
        [Key]
        public int Id { get; set; } 

         public int? TimeLineId {get;set;}

        [ForeignKey(nameof(TimeLineId))]
        [InverseProperty("TimeLinePhases")]
        public virtual TimeLine? TimeLine {get; set;}
}
  • Related