0

I want to create a direct relation between the Task entity and the child entities, to get with the task the corresponding child and when I get the child to get the corresponding task.

I have an entity named Task and I need to relate it with other entities types one2one. My solution was to create in the task entity one propriety for the child id and one for the child type:

public class Task
{
    public int Id { get; set; }
    public int ChildId { get; set; }
    public int TaskTypeId { get; set; }
    public Child1 Child1{ get; set; }
    public Child2 Child2{ get; set; }
} 

public class Child1
{
   public int Id { get; set; }
   public Task Task{get; set;}
}    

public class Child2
{
   public int Id { get; set; }
   public Task Task {get; set;}
}
2
  • Are you looking for inheritance and a discriminator column? learn.microsoft.com/en-us/ef/core/modeling/… Commented Apr 4, 2023 at 11:02
  • Something like this, but I don't know how to create the relation in model builder for every child type Commented Apr 4, 2023 at 12:19

3 Answers 3

0

The properties of Child1 and Child2 classes are the same, why did you create 2 separate classes? Wouldn't it work to do it this way with a single class?

public class Task
{
    public int Id { get; set; }
    public int TaskTypeId { get; set; }
    public IEnumerable<Child1> Childs{ get; set; }
} 

public class Child1
{
   public int Id { get; set; }
   public int TaskId { get; set; }
   public Task Task { get; set; }
}    
Sign up to request clarification or add additional context in comments.

1 Comment

there are not the same, it's a simplified example. The child1 and child2 are 2 differed objects
0

You configure your relationships by convention: https://www.entityframeworktutorial.net/efcore/conventions-in-ef-core.aspx

Therefore the naming is important Change the foreign Keys in the Task Model:

public class Task
{
    public int Id { get; set; }    
    public int TaskTypeId { get; set; }
    
    public int Child1Id { get; set; }
    public Child1 Child1{ get; set; }
    
    public int Child2Id { get; set; }
    public Child2 Child2{ get; set; }
} 

Alternative solution, relationship by Fluent API configuration: https://www.entityframeworktutorial.net/efcore/fluent-api-in-entity-framework-core.aspx With IEntityTypeConfiguration.

public class Task
{
    public int Id { get; set; }
    public int ChildId { get; set; }
    public int TaskTypeId { get; set; }
    public Child1 Child1{ get; set; }
    public Child2 Child2{ get; set; }
} 

public class Child1
{
   public int Id { get; set; }
   public Task Task{get; set;}
}    

public class Child2
{
   public int Id { get; set; }
   public Task Task {get; set;}
}

The implementtion of IEntityTypeConfiguration:

    internal class Child1DbConfig : IEntityTypeConfiguration<Child1>
    {

    public void Configure(EntityTypeBuilder<Child1> entity)
    {
                entity.ToTable("Child1");
                entity.HasKey(c => c.Id);
    
                entity.HasOne(d => d.Task)
                    .WithOne(p => p.Child1)
                    .HasForeignKey(d => d.TaskId);
    }
}

Dont forget to make a new migration after adding/editing the IEntityTypeConfiguration interface.

Also: Maybe choose another name for your Task class. Task is already a Class name in the 'System.Threading' namespace. So if you use anything async, you will run in to trouble sooner or later.

Thanks for CodeCaster for correcting my (wrong) Answer!

2 Comments

No, you don't have to do this, it all works by convention.
I have 8 child types and I don't want to create a new childId prop for every child entity. The relation is one2one, I tried you version but the problem is I have the same childId for different entities the unique combination is ChildId, TaskTypeId
0

I face same issue before, so since this is one to one table I suggest you used [Own] entity, which will map everything in the same table as the parent and remove headache.

public class Task
{
    public int Id { get; set; }
    public int ChildId { get; set; }
    public int TaskTypeId { get; set; }
    public Child1 Child1{ get; set; }
    public Child2 Child2{ get; set; }
} 

[Owned]
public class Child1
{
   public int Id { get; set; }
   public Task Task{get; set;}
}    

[Owned]
public class Child2
{
   public int Id { get; set; }
   public Task Task {get; set;}
}

Else, if you prefer them to be in separate table and you want to query them from the child, you can also make the Child.Id as the PK and FK at the same time, and referencing to Task table.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Task>()
        .HasOne(e => e.Child1)
        .WithOne(e => e.Task)
        .HasForeignKey<Child1>(e => e.Id)
        .IsRequired();

    modelBuilder.Entity<Task>()
        .HasOne(e => e.Child2)
        .WithOne(e => e.Task)
        .HasForeignKey<Child2>(e => e.Id)
        .IsRequired();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.