Inheritance in the Entity Framework

Asked

Viewed 261 times

1

I am now reading about cross domain inheritance in EF. I came across this example:

public abstract class BillingDetail
{
    public int BillingDetailId { get; set; }
    public string Owner { get; set; }
    public string Number { get; set; }
}

[Table("BankAccounts")]
public class BankAccount : BillingDetail
{
    public string BankName { get; set; }
    public string Swift { get; set; }
}

[Table("CreditCards")]
public class CreditCard : BillingDetail
{
    public int CardType { get; set; }
    public string ExpiryMonth { get; set; }
    public string ExpiryYear { get; set; }
}

public class InheritanceMappingContext : DbContext
{
    public DbSet<BillingDetail> BillingDetails { get; set; }
}

I noticed that only derived classes receive the annotation [Table("NameTable")]. Assuming then that the property Owner should be mandatory for derivative classes, ( [Required] ), and that must also have its character size limited to 50, ( [MaxLenght(50)] ). In such cases the annotation is in the parent class, correct?

2 answers

1


Correct. Assuming you want to have a table for each type. Nor could it be different, since properties do not appear in the child classes.

Of course the rest of the modeling needs to be right too :)

  • But still the parent class may be without the note [Table] ? That is, only with the annotations in the properties.

  • Yes, you do not need the note, a table will be created for it. There is an example in TPT (which seems to be what you want) to see how it is: https://datatellblog.wordpress.com/2015/04/12/inheritance-modelling-patterns-with-entity-framework-6-code-first/

0

Using the configuration of Entity Framework Fluent this is very clear, you should put these detailed settings in the inheriting settings file from the class Entitytypeconfiguration.

Observe:

public class BankAccountConfiguration: EntityTypeConfiguration<BankAccount>
{
    public BankAccountConfiguration()
    {
        ToTable("BankAccounts");

        Property(c => c.BankName)
            .IsRequired();

        Property(c => c.Swift)
            .IsRequired();
    }
}

public class CreditCardConfiguration : EntityTypeConfiguration<CreditCard>
{
    public CreditCardConfiguration()
    {
        ToTable("CreditCards");

        Property(c => c.CardType)
            .IsRequired();

        Property(c => c.ExpiryMonth)
            .IsRequired();

        Property(c => c.ExpiryYear)
            .IsRequired();
    }
}

public class BillingDetailConfiguration : EntityTypeConfiguration<BillingDetail>
{
    public BillingDetailConfiguration()
    {
        ToTable("BillingDetail");

        HasKey(c => c.BillingDetailId);

        Property(c => c.BillingDetailId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
            .IsRequired();

        Property(c => c.Number)
            .IsRequired();

        Property(c => c.Owner)
            .IsRequired()
            .HasMaxLength(50);
    }
}

Configuring the Dbcontext class

public class InheritanceMappingContext : DbContext
{

    public InheritanceMappingContext()
        :base("Conn1")
    {

    }
    public DbSet<BillingDetail> BillingDetails { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new BillingDetailConfiguration());
        modelBuilder.Configurations.Add(new BankAccountConfiguration());
        modelBuilder.Configurations.Add(new CreditCardConfiguration());
    }
}

Recording Information:

InheritanceMappingContext c = new InheritanceMappingContext();

BankAccount b = new BankAccount();
b.BankName = "N";
b.Number = "1";
b.Owner = "O";
b.Swift = "O";

c.BillingDetails.Add(b);
c.SaveChanges();

In this specific case a table was created for each configuration class and the rules placed in each configuration class, this improves the code reading, but, nothing prevents to use the annotations also

I believe that so the inheritance is very clear and your statement question is correct, where the settings are each in their place of origin.

Using Dataannotations

[Table("BillingDetail")]
public abstract class BillingDetail
{
    [Key()]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int BillingDetailId { get; set; }

    [Required()]
    [MaxLength(50)]
    public string Owner { get; set; }

    [Required()]
    public string Number { get; set; }
}

[Table("BankAccounts")]
public class BankAccount : BillingDetail
{
    [Required()]
    public string BankName { get; set; }

    [Required()]
    public string Swift { get; set; }
}

[Table("CreditCards")]
public class CreditCard : BillingDetail
{
    [Required()]
    public int CardType { get; set; }

    [Required()]
    public string ExpiryMonth { get; set; }

    [Required()]
    public string ExpiryYear { get; set; }
}
  • 2

    Yeah, I’m aware that fluent api is the top of galaxies when it comes to EF. But as I’m entering the world. net now, at this first moment I’m giving preference to Dataannotations. I want to familiarize myself with the two forms.

  • @Matheussaraiva fantastic really and congratulations on your study, it is always good to know the possible ways and use as your need, I will put with Dataanotations

  • @Matheussaraiva made the changes and put with Dataannotations https://msdn.microsoft.com/pt-br/library/system.componentmodel.dataannotations(v=vs.110). aspx

Browser other questions tagged

You are not signed in. Login or sign up in order to post.