0

I have a TPH base class, PayCaddyMessage, configured like below in my code-first model:

sealed class PayCaddyMessageConfig : PayCaddyEntityConfig<PayCaddyMessage>
{
    public PayCaddyMessageConfig()
    {
        Property(e => e.Subject)
            .IsRequired()
            .HasMaxLength(50);
        HasRequired(e => e.Sender);
        HasRequired(e => e.Receiver);
    }
}

I have a class derived from PayCaddyMessage:

public class PayBetRequest: PayCaddyMessage
{
    public string SenderId { get; set; }
    public string ReceiverId { get; set; }
    public string Description { get; set; }
    public int Amount { get; set; }
    public bool PaymentAccepted { get; set; }
}

}

I have deleted my old database, and am trying to start a new one using Migrations. When I issue the command Add-Migration Create -Force, I get an exception, with the following info:

System.Data.Entity.ModelConfiguration.ModelValidationException: One or more validation errors were detected during model generation:

ReceiverId: Name: Each property name in a type must be unique. Property name 'ReceiverId' is already defined.
SenderId: Name: Each property name in a type must be unique. Property name 'SenderId' is already defined.

I can find no duplicate property names in my code. Duh, it wouldn't compile, but what I strongly suspect is that EF adds the properties SenderId and ReceiverId to PayBetRequest as foreign keys, while they are not explicitly declared in that class, and then the derived class, PayBetRequest has these properties declared. Then, in the class created for the migration, I end up with duplicate property names.

If I ommit these poperties from the derived class, they won't be available in my code, as they are not declared on the base type, and I don't know how to declare them as foreign keys on the base type, so I have omitted them there, and HasRequired(e => e.Sender); automatically generates a SenderId in the migration.

ProfK
  • 49,207
  • 121
  • 399
  • 775
  • I don't understand why you can have `Sender` and `Receiver` in the base types, but not their foreign key properties. If you access `Sender` you indirectly access its foreign key, so it might as well be a property in the base type. Or is it that you don't know how to define the mapping? – Gert Arnold Sep 10 '15 at 21:49
  • I removed the `Id` properties fron the derived class. It has access to the `Sender` of its base, so also to `Sender.Id`. Make this an answer and I will accept. – ProfK Sep 11 '15 at 05:16

1 Answers1

0

Sender and Receiver are part of the base type, which meand that the base type indirectly has access to their foreign keys. So these FKs may as well be part of the base type:

public PayCaddyMessageConfig()
{
    Property(e => e.Subject)
        .IsRequired()
        .HasMaxLength(50);
    HasRequired(e => e.Sender).WithMany().HasForeignKey(p => p.SenderId);
    HasRequired(e => e.Receiver).WithMany().HasForeignKey(p => p.ReceiverId);
}

Or, as you say in a comment, you can remove the foreign key properties altogether. If you need an Id in a derived class you can access it by e.g. Sender.Id.

Remember though that removing the foreign key properties from the model turns the associations into independent associations in stead of foreign key associations.

Community
  • 1
  • 1
Gert Arnold
  • 105,341
  • 31
  • 202
  • 291