EF Core Navigating to 2 Properties of the Parent Class Issue

asp.net-core c# ef-core-2.0 entity-framework-core

Question

I am running a migration on a new Class I created that has 2 objects within it that reference different objects of the same type. Here is the class

public class AccountOpenerWorkflowStep 
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        public DateTime CreatedDate { get; set; }
        public DateTime ModifiedDate { get; set; }
        public string Controller { get; set; }
        public string Action { get; set; }
        public bool DefaultStep { get; set; }

        [Column("TrueWorkflowStepId")]
        public virtual AccountOpenerWorkflowStep TrueWorkflowStep { get; set; }

        [Column("FalseWorkflowStepId")]
        public virtual AccountOpenerWorkflowStep FalseWorkflowStep { get; set; }
    }

So my two properties TrueWorkflowStep and FalseWorkflowStep will point to other objects in the same table.

The issue is when I run this migration it only creates the column FalseWorkflowStep and not the True one.

Here is an except from the Migration

migrationBuilder.CreateTable(
            name: "AccountOpenerWorkflowSteps",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
                CreatedDate = table.Column<DateTime>(nullable: false),
                ModifiedDate = table.Column<DateTime>(nullable: false),
                Controller = table.Column<string>(nullable: true),
                Action = table.Column<string>(nullable: true),
                DefaultStep = table.Column<bool>(nullable: false),
                FalseWorkflowStepId = table.Column<int>(nullable: true)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_AccountOpenerWorkflowSteps", x => x.Id);
                table.ForeignKey(
                    name: "FK_AccountOpenerWorkflowSteps_AccountOpenerWorkflowSteps_False~",
                    column: x => x.FalseWorkflowStepId,
                    principalTable: "AccountOpenerWorkflowSteps",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.SetNull);
            });

As you can see it is only inserting the one column of the same type.

Can anyone tell me why it does not recognize both of these columns?

1
0
6/30/2019 3:54:04 PM

Accepted Answer

The [Column] attribute isn't appropriate here, because it should be applied to primitive properties, not references. EF just ignores the attributes (using different column names confirms this), falls back on its default mapping conventions --and then fails.

I happened to stumble upon a similar problem yesterday. EF's default conventions seem to have a hard time handling two uniform relationships in one class.

I didn't try your model in Npgsql, but with Sql Server EF fails likewise. The solution is to use the correct attribute:

[ForeignKey("TrueWorkflowStepId")]
public virtual AccountOpenerWorkflowStep TrueWorkflowStep { get; set; }

[ForeignKey("FalseWorkflowStepId")]
public virtual AccountOpenerWorkflowStep FalseWorkflowStep { get; set; }

Or fluent mapping:

modelBuilder.Entity<AccountOpenerWorkflowStep>().HasOne(x => x.TrueWorkflowStep).WithMany()
    .HasForeignKey("TrueWorkflowStepId").IsRequired(false);
modelBuilder.Entity<AccountOpenerWorkflowStep>().HasOne(x => x.FalseWorkflowStep).WithMany()
    .HasForeignKey("FalseWorkflowStepId").IsRequired(false);
2
6/30/2019 7:43:53 PM

Popular Answer

Here is the explain

EF Core only supports having one mapping in the model for each entity type. I.e. there aren't any supported cases in which two instance of the same type could end up being stored in different tables or different columns.

If you want something like this there are a couple of alternatives you can try. The most appropriate one is going to depend on your scenario:

Having two DbSets of two different types. The two types can inherit from (and even have all their properties defined in) a common base type as long as that base type isn't mapped in the EF Core model.

Having two separate derived DbContext types which map the Venda type to different tables.

So I would recommend you try to add different class that inherit same property from base class



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow