我有以下代码结构:
class Car
class Honda : Car
class Toyota : Car
当然,这会在Discriminator
表格中生成Cars
列。所以,我们有以下记录:
汽车表:
Id Discriminator Color
---------------------------
1 Honda Yellow
2 Honda Red
3 Toyota Yellow
现在,我要做的是通过为每个品牌/型号添加Car
来扩展Price
信息。但它应该是一个映射表,因为它是按汽车制造的,而不是按汽车“实例”(记录)。
类似的东西:
CarPrices 表格:
CarType Amount
------------------
Toyota 10000
Honda 11000
基本上我想要一个car.Price.Amount
属性,对于Honda
,它会获得11,000
值。
我想我可以做以下'映射':
public class CarPrice
{
public CarPrice(Car car, int amount)
{
var carType = car.GetType();
if (carType.BaseType != null && carType.Namespace == "System.Data.Entity.DynamicProxies")
{
// Get rid of the EF dynamic proxy wrapper
carType = carType.BaseType;
}
this.CarType = carType.Name;
this.Amount = amount;
}
protected CarPrice()
{
// Required by EF
}
[Required]
public int Amount { get; private set; }
[Key]
public string CarType { get; private set; }
}
但我不知道如何在Price
上执行Car
属性,该属性基于其Discriminator
映射到CarPrice
。
class Car
{
// ...
// TODO: I only need 'get'
public virtual CarPrice Price { get; }
}
我必须避免在Cars
表中添加新列,因此链接绝对必须发生在现有记录的Discriminator
列上。
我该如何处理?也许我可以使用Fluent API将car.Price
属性映射到自定义SQL查询或以某种方式将其指向CarPrices
表?
我认为解决方案将围绕Mapping Properties of an Entity Type to Multiple Tables in the Database (Entity Splitting)。
答案 0 :(得分:0)
这里没什么特别的。只需将鉴别器添加为实体属性,就可以将其用作外键属性。
EG
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data;
using System.Diagnostics;
using System.Threading.Tasks;
namespace Ef6Test
{
public class Car
{
public int Id { get; set; }
public string CarTypeName { get; set; }
[ForeignKey("CarTypeName")]
public CarType CarType { get; set; }
}
public class Honda: Car
{
}
public class Toyota : Car
{
}
public class CarType
{
[Key]
public string Name { get; set; }
public int Price { get; set; }
}
class Db : DbContext
{
public DbSet<Car> Cars { get; set; }
public DbSet<CarType> Prices { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>().Map<Honda>(c => c.Requires("CarTypeName").HasValue("Honda"));
modelBuilder.Entity<Car>().Map<Toyota>(c => c.Requires("CarTypeName").HasValue("Toyota"));
base.OnModelCreating(modelBuilder);
}
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<Db>());
using (var db = new Db())
{
db.Database.Log = m => Console.WriteLine(m);
db.Database.Initialize(true);
}
Console.WriteLine("Hit any key to exit");
Console.ReadKey();
}
}
}