Сопоставление настраиваемых типов данных Entity Framework

Учитывая этот код:

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

Где ConvertableNullable - это просто обходной путь для Nullable, но он не наследуется от него.

Теперь это мой простой контекст, где я сопоставляю класс автомобиля с сущностью и сопоставляю каждое его свойство.

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; }
}

теперь, когда я пытаюсь справиться с этим контекстом, он выдает исключение

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(); 

Какие-либо предложения??


person Mustafa Magdy    schedule 28.04.2011    source источник
comment
Кстати. CTP5 является устаревшей версией — используйте производственную версию EF 4.1 RTW.   -  person Ladislav Mrnka    schedule 28.04.2011
comment
Поддерживает ли он эту функцию?   -  person Mustafa Magdy    schedule 29.04.2011
comment
Никакие пользовательские скалярные типы не поддерживаются ни в одной версии EF.   -  person Ladislav Mrnka    schedule 29.04.2011
comment
Я нашел несколько статей, в которых говорилось о типе IUserType, который можно реализовать в NHibernate, - я не знаю, есть ли что-то подобное в EF или нет? - Проверьте этот вопрос в SO ссылка   -  person Mustafa Magdy    schedule 06.05.2011
comment
Да, в NHibernate есть эта функция, а в EF — нет.   -  person Ladislav Mrnka    schedule 06.05.2011
comment
Что-нибудь об этой функции спустя 3 года?   -  person George Mauer    schedule 25.07.2014
comment
Похоже, они наконец-то дошли до этого в EF Core 2.1. См. интерфейс IEntityTypeConfiguration. Еще не использовал его, но, похоже, решает эту проблему.   -  person ug_    schedule 17.03.2018


Ответы (2)


Единственное решение - использовать что-то вроде этого:

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

Ваше сопоставление будет:

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);

Проблема в том, что EF глобально не поддерживает пользовательские скалярные типы.

person Ladislav Mrnka    schedule 28.04.2011
comment
Что ж, это может быть хорошим решением, но учтите, что у вас более 300 таблиц со средним числом полей 15 в каждой, и они допускают нули, теперь у меня есть штраф за код для написания или генерации, какие-либо другие решения? - person Mustafa Magdy; 29.04.2011
comment
Нет, другого решения нет, и, поскольку вы сначала используете код, вам придется написать его вручную или создать какую-то умную замену. - person Ladislav Mrnka; 29.04.2011
comment
Чего я пытаюсь добиться, так это иметь динамическое свойство, с помощью которого я могу в конечном итоге сохранить сериализованный текст JSON в виде строки в таблицу. т.е. опция, похожая на MongoDb, где можно хранить весь документ JSON. это было бы только там, где нет определенной структуры таблицы и ее свойств. и пользователь может добавлять дополнительные поля во время выполнения. простой пример наличия настраиваемого поля в таблице во время выполнения. - person Anuj Pandey; 13.03.2013

«Убедитесь, что это допустимое примитивное свойство» — очевидно, проблема заключается в вашем обходном пути с нулевым значением — почему бы просто не сделать его двойным с нулевым значением?

public class Car 
{
    public virtual int CarId { get; set; }
    public virtual string TypeName { get; set; }
    public double? Price { get; set; }
}
person jcvandan    schedule 28.04.2011
comment
ну, я должен использовать этот тип для некоторых других задач, - person Mustafa Magdy; 28.04.2011
comment
да, но в исключении указано, что вы должны использовать примитивный тип, поэтому вам придется найти другой способ добиться того, что вам нужно, с помощью пользовательского класса с нулевым значением - person jcvandan; 28.04.2011
comment
Я не могу, экс. Я уже разработал приложение, которое использовало какой-то фреймворк ADO.NET, и мы планировали перейти на EF, но столкнулись с некоторыми проблемами, одна из которых заключалась в том, что многие поля базы данных были разрешены NULL, поэтому, когда EF отображает их, он преобразует их в Nullable, теперь проблема в том, if(myobj.SomeNullableDate.Month › 1) dosomething; не будет компилироваться, потому что ему нужно либо .Value, либо .GetValueOrDefault(), поэтому у меня есть решение сделать обнуляемый пользовательский обнуляемый и сделать из него неявное преобразование, поэтому я не могу сделать это другими способами (до сих пор);), любой Идеи ?? - person Mustafa Magdy; 28.04.2011
comment
если честно - судя по вашей ситуации, может быть лучше просто НЕ переходить на структуру сущностей! - person jcvandan; 03.05.2011
comment
Рассмотрим другой ORM? Например, NHibernate поддерживает этот сценарий (и многие другие, которых нет в EF). Другим вариантом может быть микро ORM, такой как Dapper или Massive, где было бы легко добавить поддержку. - person Brian Low; 21.10.2013