entity framework custom data type mapping
Asked Answered
C

2

4

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??

Clarissaclarisse answered 28/4, 2011 at 15:16 Comment(7)
Btw. CTP5 is outdated version - use production release EF 4.1 RTWSavoyard
Does it support this feature ?Clarissaclarisse
No custom scalar types are not supported in any EF version.Savoyard
I found some articles talking about IUserType type, that can be implemented in NHibernate, - I don't know is there is something like this in EF or not? - Check this question in SO linkClarissaclarisse
Yes, NHibernate has this feature but EF doesn't.Savoyard
Any word on this feature 3 years later?Nureyev
Looks like they finally got around to this in EF Core 2.1. See the IEntityTypeConfiguration interface. Havent used it yet but it looks to solve this.Respectful
S
1

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.

Savoyard answered 28/4, 2011 at 19:26 Comment(3)
Well, this could be a good work around, but consider that you've more than 300 table with average 15 field each, and they allow nulls, now I've a penalty of code to write or to generate, any other solutions ?Clarissaclarisse
No there is no other solution and because you are using code first you will have to write it manually or create some clever "replace".Savoyard
What I am trying to achieve by this is to have a dynamic property by which I can then end up stored JSON serialized text as string into table. ie. a MongoDb like option where Entire JSON document can be stored. this would only where there is no defined structure of table and its properties. and user can add more fields at run time. simple example of having custom field in a table at run time.Sava
P
0

"Make sure that it is a valid primitive property" - clearly the problem lies with your Nullable workaround - why not just make it a nullable double?

public class Car 
{
    public virtual int CarId { get; set; }
    public virtual string TypeName { get; set; }
    public double? Price { get; set; }
}
Pulitzer answered 28/4, 2011 at 15:39 Comment(5)
well, i've to use this type for some other issues,Clarissaclarisse
yes but the exception states that you must use a primitive type, so you will have to find another way of acheiving what you need with the custom nullable classPulitzer
I can't, ex. i've already developed application that was using some sort of ADO.NET framework, and we were planning to move to EF, but we face some problems, one of it, that many fields of the database were "Allow NULL", so when EF maps them, it converts them to Nullable, now the problem is "if(myobj.SomeNullableDate.Month > 1) dosomething;" will not compile, because it needs either ".Value", or ".GetValueOrDefault()" so I got a solution to make the nullable custom nullable and make implicit conversion from it, so i cannot make this any other ways (till now) ;), any Ideas ??Clarissaclarisse
to be honest - from the sounds of your situation it may be best to just NOT move over to entity framework!Pulitzer
Consider another ORM? For example NHibernate supports this scenario (and many others that EF doesn't). Another option would be a micro ORM like Dapper or Massive where it would be easy to add support.Finch

© 2022 - 2024 — McMap. All rights reserved.