3

I have a "base" entity with some properties that's being used by a bunch of other stuff (repository patterns, queues, etc) in some shared libraries. Mapped to a pluralized table.

I need to add a property to it for my specific implementation, and I want to reuse all the rest of the normal behaviors.

I derive a class:

public interface IItem {
    [Key]
    Guid Id { get; set; }
    string Name { get; set; }
}

public class Item : IItem {
    [Key]
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public interface IExtended {
    bool IsExtended { get; set; }
}

[Table("Items")]        // <-- my nemesis
public class ExtendedItem : Item, IExtended {
    [Column("_Extended")]
    public bool IsExtended { get; set; }
}

I set up the code-first context:

public class MyContext : DbContext {
    public MyContext(string connectionString) : base(connectionString) {
        // manually creating the tables, no migrations
        Database.SetInitializer<EfQueueContext>(null);
    }

    public DbSet<Item> Items { get; set; }
}
  • Without DataAnnotation [Table] I get exception "Invalid column name 'Discriminator'" -- okay, weird but makes sense
  • With [NotMapped] I get exception "The entity type ExtendedItem is not part of the model for the current context" -- okay, makes sense
  • With annotation [Table("Item"] I get exception "table 'dbo.Item' doesn't exist" -- okay, duh forgot it pluralized original
  • With annotation [Table("Items")] I get exception "table 'dbo.Items1' doesn't exist" -- what??? where did the 1 suffix come from?
  • Even creating a brand-new DbContext that only refers to ExtendedItem and not Item still adds the '1' (update - I didn't actually create a clean instance; see comment on answer)
Community
  • 1
  • 1
drzaus
  • 24,171
  • 16
  • 142
  • 201
  • What if you use `[Table("Something")]` instead of "Items"? It might just conflict with the Item class. – Jeroen Vannevel Mar 13 '15 at 18:39
  • I believe `class Item` receives table name `Items`. So for `class ExtendedItem` it should be something else, like `ExtendedItems`. – abatishchev Mar 13 '15 at 18:40
  • Ok, I see. So you want to keep Item and ExtendedItem in the same table Items? Make sure EF supports the way you want it to work. Not sure here. – abatishchev Mar 13 '15 at 18:42
  • Anyway, the source of the names conflict is the lack of annotation for class Item so it automatically receives a pluralized name Items. – abatishchev Mar 13 '15 at 18:43
  • @abatishchev You're supposed to be able to manually specify table names with annotations/fluent-api, but my real problem is that when I specify the exact, existing table name ("Items") something decided to append a "1" rather than use what I told it to. I've update the question slightly to emphasize that problem. – drzaus Mar 13 '15 at 18:49
  • Try applying the `[Table("Items")] ` annotation in both entities (`Item` and `ExtendedItem`). – ocuenca Mar 13 '15 at 18:49

1 Answers1

0

The problem is EF deduce you want to create a Table per Type (TPT) when you apply the Table atribute on the subclasses to specify the mapped table name. In your case you are trying to rename the table related with theExtendedItem entity, but you are using the same name of the root table, that's way EF is creating two tables one called Items1 (because you already use the Items name in the inheriting entity) related to the Item entity and another called Items related to the ExtentedItem entity

If you want to create a Table per Hierarchy (TPH) and you want to rename the root table, then you need to apply the [Table("Items")] data annotation on the root entity (Item) and all entities that inherit from it.

ocuenca
  • 38,548
  • 11
  • 89
  • 102
  • This sounds right -- I didn't actually try it, because I found out I was accidentally inheriting the original `MyContext` rather than from `DbContext`, meaning that both `Item` and `ExtendedItem` were `DbSets`. Once I started from a fresh `DbContext` without `Item` declared, I only needed to rename `ExtendedItem`. – drzaus Mar 16 '15 at 14:25