Самое близкое, я думаю, вы сможете найти то, что подходит как для реляционной, так и для объектно-ориентированной стороны, - это сопоставление и объектную модель с абстракцией TPC в базе данных, которая уже очень близка к таблице.структура у вас есть.Для простоты я покажу это, используя Code First в EF 4.3.1.
Давайте определим простую объектную модель, например, так:
public class Property
{
public int Id { get; set; }
public string Name { get; set; }
public int ValueId { get; set; }
public virtual Value Value { get; set; }
}
public abstract class Value
{
public int Id { get; set; }
}
public class ValueString : Value
{
public string Value { get; set; }
public override string ToString()
{
return "String value of " + Value;
}
}
public class ValueInteger : Value
{
public int Value { get; set; }
public override string ToString()
{
return "Integer value of " + Value;
}
}
public class ValueBoolean : Value
{
public bool Value { get; set; }
public override string ToString()
{
return "Boolean value of " + Value;
}
}
(я вставил некоторые методы ToString только для того, чтобыЛегко увидеть, что происходит, когда мы используем эти классы.)
Это можно сопоставить с помощью TPC, чтобы каждый тип получил свою собственную таблицу:
public class PropertyAndValuesContext : DbContext
{
public DbSet<Property> Properties { get; set; }
public DbSet<Value> Values { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ValueString>().Map(
m =>
{
m.MapInheritedProperties();
m.ToTable("ValueString");
});
modelBuilder.Entity<ValueInteger>().Map(
m =>
{
m.MapInheritedProperties();
m.ToTable("ValueInteger");
});
modelBuilder.Entity<ValueBoolean>().Map(
m =>
{
m.MapInheritedProperties();
m.ToTable("ValueBoolean");
});
}
}
Итак, теперь у нас есть таблицысоответствует макету, который вы указали в начале вашего вопроса, за исключением того, что условный столбец TypeId отсутствует, поскольку он здесь не нужен.
Давайте напишем инициализатор и консольное приложение, чтобы добавить некоторые тестовые данные и отобразить их:
public class TestInitializer : DropCreateDatabaseAlways<PropertyAndValuesContext>
{
protected override void Seed(PropertyAndValuesContext context)
{
new List<Property>
{
new Property { Name = "PropWithBool", Value = new ValueBoolean { Id = 1, Value = true } },
new Property { Name = "PropWithString1", Value = new ValueString { Id = 2, Value = "Magic" } },
new Property { Name = "PropWithString2", Value = new ValueString { Id = 3, Value = "Unicorn" } },
new Property { Name = "PropWithInt1", Value = new ValueInteger { Id = 4, Value = 6 } },
new Property { Name = "PropWithInt2", Value = new ValueInteger { Id = 5, Value = 7 } },
}.ForEach(p => context.Properties.Add(p));
}
}
public class Program
{
public static void Main(string[] args)
{
Database.SetInitializer(new TestInitializer());
using (var context = new PropertyAndValuesContext())
{
foreach (var property in context.Properties)
{
Console.WriteLine("{0} with {1}", property.Name, property.Value);
}
}
}
}
Выполнение этой распечатки:
PropWithBool with Boolean value of True
PropWithString1 with String value of Magic
PropWithString2 with String value of Unicorn
PropWithInt1 with Integer value of 6
PropWithInt2 with Integer value of 7
Вы можете легко добавлять различные типы значений, сохранять их в соответствующих таблицах и затем запрашиватьэти значения обратно.
Теперь, может быть, вы действительно хотите, чтобы свойство возвращало значение, напечатанное как «объект», как в вашем примере.Что ж, теперь мы можем сделать это с помощью простого абстрактного свойства:
public abstract class Value
{
public int Id { get; set; }
public abstract object TheValue { get; set; }
}
public class ValueString : Value
{
public string Value { get; set; }
public override object TheValue
{
get { return Value; }
set { Value = (string)value; }
}
public override string ToString()
{
return "String value of " + Value;
}
}
public class ValueInteger : Value
{
public int Value { get; set; }
public override object TheValue
{
get { return Value; }
set { Value = (int)value; }
}
public override string ToString()
{
return "Integer value of " + Value;
}
}
public class ValueBoolean : Value
{
public bool Value { get; set; }
public override object TheValue
{
get { return Value; }
set { Value = (bool)value; }
}
public override string ToString()
{
return "Boolean value of " + Value;
}
}
Вы также можете представить, что делаете это, если хотите:
public class Property
{
public int Id { get; set; }
public string Name { get; set; }
public int ValueId { get; set; }
public virtual Value Value { get; set; }
public object TheValue
{
get { return Value.TheValue; }
set { Value.TheValue = value; }
}
}
Наконец, если вам действительно нужно свойство TypeId/ column в сущности / таблице Property, затем вы можете добавить его, но вам нужно убедиться, что вы установили для него какое-то подходящее значение, так как оно не требуется для отображения.