WARNING: EF Code first may only be appropriate for children

I would like to warn anybody who wants to use code first (specifically TPC inheritance) to only use it when you plan to stick with the simple scenarios that you’ve already seen proven out through examples on the web.  Once you begin to stray from these examples, you’ll find yourself with code that doesn’t work with no way to fix it (since, per the Microsoft way, the important classes are all “private internal”).  Here are just a few examples of limitations that I’ve encountered:

1) If you want an entity base class that is not abstract (to, say, work around a bug in RIA services) with a TPC (Table per Concrete Type) configuration, forget about it… there is absolutely no way to do it.

2) Generic types are not supported as entities or as entity base types.

3) If you want to define the properties on your entity at runtime, using ICustomTypeProvider or IDynamicMetaObjectProvider… again, forget about it.

I could go on and on, but the point is that I’ve run into more “not supported” scenarios with this library than almost any other I’ve ever used.  That said, I love the concept… and once EF code first becomes at all extensible, I’ll fully support it.

9 comments so far

  1. Eivind on

    I’m using EF 5.0(rc) code first, and I’m using both non-abstract base-entity and generic base-entities without problems…
    So it is incorrect when you say that it is not supported.

    I haven’t used any previous versions so I don’t know if this is something new in 5.0.

    But I’m used to getting a lot of pain from microsoft-frameworks in the past (sync framework and linq-to-sql) because of poor design and lack of extension-points, so I will not be suprised if I run into problems with EF too.

    • joshmouch on

      Is your non-abstract base-entity a TPC setup? They do support TPT, but in order to get TPC, your base entity has to be abstract. I’ve reflected the code that forces this to occur and there is no possible extension point to change it.

      • Eivind on

        It is tpc, very simplified it is like this:
        class Base
        {
        public Guid Id { get; set; }
        }
        class Generic : Base
        {
        public T Value { get; set; }
        }
        class Concrete : Generic
        {
        public string Something { get; set; }
        }
        …..
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        modelBuilder.Entity().Map(p =>
        {
        p.MapInheritedProperties();
        p.ToTable(“Concrete”);
        });

        base.OnModelCreating(modelBuilder);
        }

    • joshmouch on

      I’ve updated the post to specify TPC, which is what I am using.

  2. Eivind on

    Formatting and the generic brackets disappered from my post…

    • Eivind on
      • joshmouch on

        If you change the type of Context.Concretes to DbSet<Base> and then add a second implementation (e.g. Concrete2 : Generic<string>), does that work for you?

      • Eivind on

        I can add another concrete class, but if i change to DbSet I get “The entity type Base is not part of the model for the current context”

      • joshmouch on

        Yeah, I think that is because of the generic type on top of Base. The DbContext ignores that class and therefore ignores Base.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: