This is parent abstract class :
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
This is a child abstract class :
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; }
}
And these are another children classes:
public class RequestTaxi : TransportRequest
{
}
public class RequestVanet: TransportRequest
{
}
public class RequestWomenTaxi : TransportRequest
{
}
public class RequestMotorCycle: TransportRequest
{
}
public class RequestLuxaryTaxi: TransportRequest
{
}
And this is my ApplicationDBContext class related code :
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));
And this is my migration class :
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");
}
My question is why added some column like these :
RequestMotorCycle_DirectionPoints
and repeated for every five children class ?
In fact I have six DirectionPoints column!!!
How can I have only one DirectionPoints for example ?
The problem is that all these properties are defined in the TransportRequest
class, but TransportRequest
is not specified to be an entity (only the Request
and the final derived entities), hence EF Core assumes it's just a base class, and all derived classes properties are different.
The Including & Excluding Types section of the EF Core documentation explains what classes are identified as entities:
By convention, types that are exposed in
DbSet
properties on your context are included in your model. In addition, types that are mentioned in theOnModelCreating
method are also included. Finally, any types that are found by recursively exploring the navigation properties of discovered types are also included in the model.
As you can see, TransportRequest
is not a DbSet
, not mentioned in the OnModelCreating
and not referenced by navigation property.
To fix the issue, simply "mention" it in the OnModelCreating
:
// ...
model.Entity<TransportRequest>();
// ...