Search code examples
c#mappingef-code-firstentity-framework-4.1entity-framework-ctp5

entity framework custom data type mapping


Given this code:

public class Car 
{
    public virtual int CarId { get; set; }
    public virtual string TypeName { get; set; }
    public ConvertableNullable<double> Price { get; set; }
}

Where the ConvertableNullable is just a workaround to Nullable, but it doesn't inherit from it.

Now, this my simple context, where i map, the car class to entity, and map every property of it

public class MyDBContext : DbContext {
   public MyDBContext() : base(
       "data source=.;initial catalog=newDB1;integrated security=True;" + 
        "multipleactiveresultsets=True;App=EntityFramework")
   { }

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
   {
       base.OnModelCreating(modelBuilder);

       modelBuilder.Entity<Car>().HasKey(x=>x.CarId);
       modelBuilder.Entity<Car>().Property(x => x.TypeName);
       modelBuilder.Entity<Car>().Property(x => x.Price);
   }

    public DbSet<Car> Cars { get; set; }
}

now when i try to deal with this context, it throws an exception

var db = new MyDBContext();

// Throws exception "The property 'Price' is not a declared 
// property on type 'Car'. 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."
var c = db.Cars.ToList(); 

Any suggestions??


Solution

  • The only solution is using something like this:

    public class Car 
    {
        public virtual int CarId { get; set; }
        public virtual string TypeName { get; set; }
        // This must be accessible to the mapping 
        public double? PriceData { get; set; } 
    
        public ConvertableNullable<double> Price 
        { 
            get { // Return data from PriceData }
            set { // Set data to PriceData }
        }
    }
    

    Your mapping will be:

    modelBuilder.Entity<Car>().HasKey(x=>x.CarId);
    modelBuilder.Entity<Car>().Property(x => x.TypeName);
    modelBuilder.Entity<Car>().Property(x => x.PriceData).HasColumnName("Price");
    modelBuilder.Entity<Car>().Ignore(x => x.Price);
    

    The problem is that EF globally doesn't have support for custom scalar types.