2

I am using EF 5 Beta 2 Code-First. I have created an edmx file which has 2 entities among others named Brand and Vehicle.

One Brand can have zero or more (many) Vehicles and every Vehicle should have a Brand (required). Vehicle has a foreign key named BrandID which is non-nullable.

(relationship)   
    Brand  +------------------->  Vehicle
          (1)                  (*)

Also I did use EF 5 DbContext Generator to create POCO classes.

The Problem

When I try to either Read or Write records, I get the following error:

error 3023: Problem in mapping fragments starting at line 155:Column Vehicle.BrandID in table Vehicle must be mapped: It has no default value and is not nullable.

Notice: I am using TPC inheritance mapping where Vehicle is an abstract base class from which 2 classes (Car & Motorbike) are being derived.

Here is class definition plus related fluent API code:

//------------ Class definiions ---------------

public abstract partial class Vehicle
{
    public int VehicleID { get; set; }
    public short BrandID { get; set; }

    public virtual Brand Brand { get; set;
}

public partial class Car : Vehicle
{
    public string BodyType { get; set; }
}

public partial class Motorbike : Vehicle
{
}

public partial class Brand
{
    public Brand()
    {
        this.Vehicles = new HashSet<Vehicle>();
    }        

    public short BrandID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Vehicle> Vehicles { get; set; }
}


//--------------- Fluent API code ---------------

modelBuilder.Entity<Vehicle>()
    .Property(p => p.VehicleID)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);    

modelBuilder.Entity<Car>()
    .Map(m =>
    {
        m.ToTable("Car");
        m.MapInheritedProperties();
    });

modelBuilder.Entity<Motorbike>()
    .Map(m =>
    {
        m.ToTable("Motorbike");
        m.MapInheritedProperties();
    });

modelBuilder.Entity<Brand>()
    .HasMany(b=>b.Vehicles)
    .WithRequired(v=>v.Brand)
    .HasForeignKey(p => p.BrandID);


modelBuilder.Entity<Brand>()
    .Property(p => p.BrandID)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

This is so strange since everything seems OK and has been checked several times.

Any thoughts would be greatly appreciated.

om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
Kamran
  • 782
  • 10
  • 35
  • Do you really have a `Vehicle` table as the exception says? I'm wondering because if you use TPC you should not have a table for the abstract base class, only for the two concrete classes `Car` and `Motorbike`. Also: Do you have a connection string with all the edm metadata stuff in it? I would expect that because apparently you use Model-First. But I'm wondering why you have Fluent API mapping code, which is Code-First and not Model-First. – Slauma Apr 01 '12 at 11:29
  • @Slauma: 1. Another strange thing - as you mentioned - is that I have a `Vehicle` class, while this does not happen for another abstract base class named `Ad` and its derived classes. 2. My connection string is as follows: 3. About Model-First: first I used EDM Designer to model my entities visually. Then I used **EF DbContext Generator** to create POCO classes and `DbContext`. Finally I used EF + Fluent API to create the databse. – Kamran Apr 01 '12 at 15:48
  • 1
    Perhaps it would help if you show the full mapping in Fluent API for the classes above, especially also the TPC mapping. Having a navigation property (`Brand`) on the *base class* (`Vehicle`) is a possible problem with TPC: 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 (see section "Polymorphic Associations with TPC is Problematic" in this article). – Slauma Apr 01 '12 at 16:25
  • I have added Fluent API code to the main question above. Would you take a look please? – Kamran Apr 01 '12 at 18:07

1 Answers1

1

TPC inheritance just doesn't work for this kind of model where you have a navigation property on the base type:

...using TPC in the EF forces you to avoid associations in your base type...

(Quote from here: http://blogs.msdn.com/b/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx)

You must use TPT or TPH inheritance for your model.

Slauma
  • 175,098
  • 59
  • 401
  • 420