Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework 4.1 Code First: Get all Entities with a specific base class

I have a DbContext with set up different DbSet<T>s with all types that derive from the same base class:

public class Foo : Entity { }
public class Bar : Entity { }

MyDbContext : DbContext
{
  public DbSet<Foo> Foos { get; set; }
  public DbSet<Bar> Bars { get; set; }
}

Is it possible to get all entities which have the Entitybase class in one query, like:

DbContext.Set<Entity>();  // doesn't work

I tried to introduce an explicit DbSet<Entity> to the DbContext, but that results in one big table for all entities in the database.

Additional question: If this works somehow, what about querying for interfaces?

Edit:

I followed the instructions on Ladislav Mrnka's link and did my mappings like follows:

MyDbContext : DbContext
{
  public DbSet<Entity> Entities { get; set; }

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    // Foo
    modelBuilder.Entity<Foo>().Map(x =>
    {
      x.MapInheritedProperties();
      x.ToTable("Foo");
    })
    .HasMany(x => x.Tags).WithMany();

    modelBuilder.Entity<Foo>()
        .Property(x => x.Id)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

    // Bar
    // same thing for Bar and a bunch of other Entities

    base.OnModelCreating(modelBuilder);
  }
}

This throws now the error

The property 'Id' is not a declared property on type 'Foo'. Verify that the property has not been explicitly excluded from the model by using the Ignore method or NotMappedAttribute data annotation. Make sure that it is a valid primitive property.

I also tried to set the Key explicitly to the Id property:

modelBuilder.Entity<Foo>().Map(x => {...})
  .HasKey(x => x.Id)
  .HasMany(x => x.Tags).WithMany();

What am I missing?

like image 907
davehauser Avatar asked Apr 28 '11 13:04

davehauser


2 Answers

You need to introduce TPC inheritance. After that DbContext.Set<Entity>() will work and you will still have table per entity.

like image 200
Ladislav Mrnka Avatar answered Nov 20 '22 04:11

Ladislav Mrnka


Just to your problem in your Edit section:

The error message indicates that you have the Id key property in your base class Entity. Then you need to configure the key property on this class and not on the derived Foo class:

modelBuilder.Entity<Entity>()
    .Property(x => x.Id)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
like image 33
Slauma Avatar answered Nov 20 '22 02:11

Slauma