Проблема наследования ядра EF (HasDiscriminator) - PullRequest
0 голосов
/ 08 июня 2018

Это родительский абстрактный класс:

public enum RequestType
{
    TaxiRequester,
    WomenTaxiRequester,
    LuxaryTaxiRequester,
    MotrCycleRequester,
    VanetRequester
}
public enum PaymentType
{
    Cash = 0,
    Credit=1,
    Free=2
}

public abstract class Request
{
    protected Request()
    {
        PersonsRequests = new HashSet<PersonRequest>();
        WorkerRequestNotification= new HashSet<WorkerRequestNotification>();
    }

    #region EFValidator

    [Required]
    [Key]
    #endregion

    public Guid RequestId { get; set; }
    #region EFValidator

    [Required]

    #endregion

    public string CodeSafar { get; set; }

    #region EFValidator

    [Required]

    #endregion

    public DateTime RequestDate { get; set; }
    #region EFValidator

    [Required]

    #endregion

    public DateTime RequestWorkDate { get; set; }

    #region EFValidator

    [Column(TypeName = "nvarchar(max)")]

    #endregion

    public string DestinationAddress { get; set; }
    #region EFValidator

    [Column(TypeName = "nvarchar(max)")]
    [Required]
    #endregion

    public string DestinationLat { get; set; }
    #region EFValidator

    [Column(TypeName = "nvarchar(max)")]
    [Required]
    #endregion

    public string DestinationLon { get; set; }
    #region EFValidator

    [Required]

    #endregion
    public DateTime ApproveDate { get; set; }
    public DateTime DoneDate { get; set; }
    #region EFValidator

    [Required]

    #endregion

    public long Price { get; set; }
    #region EFValidator

    [Required]

    #endregion

    public Status Status { get; set; }
    #region EFValidator

    [Required]

    #endregion

    public PaymentType PaymentType { get; set; }

    #region EFRelation
    public virtual ICollection<PersonRequest> PersonsRequests { get; set; }
    public virtual ICollection<WorkerRequestNotification> WorkerRequestNotification { get; set; }
    public virtual ICollection<Chat> Chats { get; set; }

    #endregion

    #region RatingRelations

    public virtual Rating Rating { get; set; }

    #endregion

Это дочерний абстрактный класс:

public abstract class TransportRequest : Request
{
    #region EFValidator

    [Required]
    [Column(TypeName = "nvarchar(max)")]

    #endregion

    public string SourceAddress { get; set; }
    #region EFValidator

    [Required]
    [Column(TypeName = "nvarchar(max)")]

    #endregion

    public string SourceLat { get; set; }
    #region EFValidator

    [Required]
    [Column(TypeName = "nvarchar(max)")]

    #endregion

    public string SourceLon { get; set; }

    #region EFValidator

    [Required]

    #endregion

    public double Distance { get; set; }
    #region EFValidator

    [Column(TypeName = "nvarchar(max)")]

    #endregion

    public string DirectionPoints { get; set; }
}

И это еще один дочерний класс:

public class RequestTaxi : TransportRequest
{

}
public class RequestVanet: TransportRequest
{

}
 public class RequestWomenTaxi : TransportRequest
{

}
 public class RequestMotorCycle: TransportRequest
{

}
public class RequestLuxaryTaxi: TransportRequest
{

}

И это мой код, связанный с классом ApplicationDBContext:

model.Entity<Request>()
            .HasMany(p => p.Chats)
            .WithOne(b => b.Request)
            .HasForeignKey(p => p.RequestId);
        model.Entity<Request>()
            .HasMany(p => p.PersonsRequests)
            .WithOne(b => b.Request)
            .HasForeignKey(p => p.RequestId);
        model.Entity<Request>()
            .HasOne(p => p.Rating)
            .WithOne(b => b.Request)
            .HasForeignKey<Rating>(p => p.RequestId);
        model.Entity<Request>()
            .HasMany(p => p.WorkerRequestNotification)
            .WithOne(b => b.Request)
            .HasForeignKey(p => p.RequestId);

        model.Entity<Request>().Property(p => p.RequestId).ValueGeneratedOnAdd();
        model.Entity<Request>()
            .HasDiscriminator<int>(name: "Type")
            .HasValue<RequestTaxi>(value: Convert.ToInt32(value: RequestType.TaxiRequester))
            .HasValue<RequestWomenTaxi>(value: Convert.ToInt32(value: RequestType.WomenTaxiRequester))
            .HasValue<RequestLuxaryTaxi>(value: Convert.ToInt32(value: RequestType.LuxaryTaxiRequester))
            .HasValue<RequestMotorCycle>(value: Convert.ToInt32(value: RequestType.MotrCycleRequester))
            .HasValue<RequestVanet>(value: Convert.ToInt32(value: RequestType.VanetRequester));

И это мой класс миграции:

protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropIndex(
            name: "IX_Request_CodeSafar",
            table: "Request");

        migrationBuilder.AlterColumn<string>(
            name: "CodeSafar",
            table: "Request",
            nullable: false,
            oldClrType: typeof(string));

        migrationBuilder.AddColumn<string>(
            name: "RequestMotorCycle_DirectionPoints",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<double>(
            name: "RequestMotorCycle_Distance",
            table: "Request",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestMotorCycle_SourceAddress",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestMotorCycle_SourceLat",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestMotorCycle_SourceLon",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestTaxi_DirectionPoints",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<double>(
            name: "RequestTaxi_Distance",
            table: "Request",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestTaxi_SourceAddress",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestTaxi_SourceLat",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestTaxi_SourceLon",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestVanet_DirectionPoints",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<double>(
            name: "RequestVanet_Distance",
            table: "Request",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestVanet_SourceAddress",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestVanet_SourceLat",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestVanet_SourceLon",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestWomenTaxi_DirectionPoints",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<double>(
            name: "RequestWomenTaxi_Distance",
            table: "Request",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestWomenTaxi_SourceAddress",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestWomenTaxi_SourceLat",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.AddColumn<string>(
            name: "RequestWomenTaxi_SourceLon",
            table: "Request",
            type: "nvarchar(max)",
            nullable: true);

        migrationBuilder.CreateIndex(
            name: "IX_Person_ApplicationUsersId1",
            table: "Person",
            column: "ApplicationUsersId",
            unique: true);

        migrationBuilder.CreateIndex(
            name: "IX_Person_ApplicationUsersId2",
            table: "Person",
            column: "ApplicationUsersId",
            unique: true);

        migrationBuilder.CreateIndex(
            name: "IX_Person_ApplicationUsersId3",
            table: "Person",
            column: "ApplicationUsersId",
            unique: true);

        migrationBuilder.AddForeignKey(
            name: "FK_Person_ApplicationUsers_ApplicationUsersId1",
            table: "Person",
            column: "ApplicationUsersId",
            principalTable: "ApplicationUsers",
            principalColumn: "Id");

        migrationBuilder.AddForeignKey(
            name: "FK_Person_ApplicationUsers_ApplicationUsersId2",
            table: "Person",
            column: "ApplicationUsersId",
            principalTable: "ApplicationUsers",
            principalColumn: "Id");

        migrationBuilder.AddForeignKey(
            name: "FK_Person_ApplicationUsers_ApplicationUsersId3",
            table: "Person",
            column: "ApplicationUsersId",
            principalTable: "ApplicationUsers",
            principalColumn: "Id");
    }

У меня вопрос, почему был добавлен такой столбец, как эти:

RequestMotorCycle_DirectionPoints

и повторяется для каждых пяти дочерних классов?

На самом деле у меня есть шесть столбцов DirectionPoints !!!

Как я могу иметь только одну DirectionPointsнапример?

1 Ответ

0 голосов
/ 08 июня 2018

Проблема заключается в том, что все эти свойства определены в классе TransportRequest, но TransportRequest не указывается как сущность (только Request и конечные производные сущности), следовательно,EF Core предполагает, что это просто базовый класс, а свойства всех производных классов различны.

В разделе Включая и исключая типы документации EF Core объясняется, какие классы определены как сущностей:

По соглашению, типы, предоставляемые в свойствах DbSet вашего контекста, включаются в вашу модель.Кроме того, типы, упомянутые в методе OnModelCreating, также включены.Наконец, любые типы, которые обнаруживаются путем рекурсивного исследования навигационных свойств обнаруженных типов, также включаются в модель.

Как видите, TransportRequest не является DbSet, не упомянутым вOnModelCreating и на него не ссылается свойство навигации.

Чтобы устранить проблему, просто "упомяните" ее в OnModelCreating:

// ...
model.Entity<TransportRequest>();
// ...
...