Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure multiple object sets per type in Entity Framework code first

I am using Entity Framework 5 code first. In my database I have 2 tables, AvailPayPeriods and AvailPayPeriodsWeekly. They both look the same:

Period datetime not null

Because these 2 tables are identical in nature I decide to create the following class to represent either 1 of the 2:

public class PayPeriod : IEntity
{
     public int Id { get; set; }

     public DateTime Period { get; set; }
}

I'm struggling to configure the 2. I have the following in my database context class:

public DbSet<PayPeriod> WeeklyPayPeriods { get; set; }
public DbSet<PayPeriod> MonthlyPayPeriods { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     modelBuilder.Configurations.Add(new WeeklyPayPeriodConfiguration());
     // Haven't yet created the configuration file for monthly pay periods
}

My WeeklyPayPeriodConfiguration class:

class WeeklyPayPeriodConfiguration : EntityTypeConfiguration<PayPeriod>
{
     internal WeeklyPayPeriodConfiguration()
     {
          this.ToTable("AvailPayPeriodsWeekly");
     }
}

When I call my repository to get back the weekly pay periods I get the following error:

Multiple object sets per type are not supported. The object sets 'WeeklyPayPeriods' and 'MonthlyPayPeriods' can both contain instances of type 'ePaySlips.DomainModel.Entities.PayPeriod'.

How do I map the 2 to their respective tables?

Should I rather create to separate classes called WeeklyPayPeriod and MonthlyPayPeriod?

like image 814
Brendan Vogt Avatar asked Feb 15 '13 11:02

Brendan Vogt


2 Answers

You could add the following classes:

public class MonthlyPayPeriod : PayPeriod
{

}

public class WeeklyPayPeriod : PayPeriod
{

}

and amend your DbContext to:

public DbSet<WeeklyPayPeriod> WeeklyPayPeriods { get; set; }
public DbSet<MnthlyPayPeriod> MonthlyPayPeriods { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
        modelBuilder.Entity<WeeklyPayPeriod>().Map(m =>
                                                       {
                                                           m.MapInheritedProperties();
                                                           m.ToTable("AvailPayPeriodsWeekly");
                                                       });
        modelBuilder.Entity<MonthlyPayPeriod>().Map(m =>
                                                       {
                                                           m.MapInheritedProperties();
                                                           m.ToTable("AvailPayPeriodsMonthly");
                                                       });

}

Not perfect but gets the job done.

like image 74
Matt Whetton Avatar answered Oct 05 '22 13:10

Matt Whetton


Following on from the accepted answer the error occurs from declaring DbSet twice with the same type. When this occurs the entity framework can't resolve which DbSet instance to use for PayPeriod entities. Using separate classes allows EF to resolve to the correct DbSet.

//Error with DbSet<PayPeriod> defined twice    
public DbSet<PayPeriod> WeeklyPayPeriods { get; set; }
public DbSet<PayPeriod> MonthlyPayPeriods { get; set; }

//EF can resolve to each  DbSet, but can't store the baseclass PayPeriods
public DbSet<WeeklyPayPeriod> WeeklyPayPeriods { get; set; }
public DbSet<MnthlyPayPeriod> MonthlyPayPeriods { get; set; }

See Related: Entity Framework 4 Code Only Error “Multiple objects sets per type are not supported”

http://weblogs.asp.net/manavi/archive/2011/01/03/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type-tpc-and-choosing-strategy-guidelines.aspx For implementing Table Per Concrete Type Mappings (TPC).

like image 40
Donald Webb Avatar answered Oct 05 '22 11:10

Donald Webb