2017-09-19 4 views
0

に私は次のコードの構造を有する:もちろんは、Entity Frameworkの生成されたテーブルにリンクテーブルを追加し、識別カラム

class Car 
class Honda : Car 
class Toyota : Car 

これはCarsテーブル内Discriminator列を生成します。

テーブル::だから、私たちはのようなレコードを持っていると思います

Id Discriminator Color 
--------------------------- 
1 Honda   Yellow 
2 Honda   Red 
3 Toyota   Yellow 

は今、私は何をしたいのメイク/モデルごとPriceを追加することにより、Car情報を拡張しています。しかし、それはマッピングテーブルでなければなりません。なぜなら、それは車ごとのものであり、車のインスタンス(記録)によるものではないからです。

のような何か:

CarPricesテーブル:

CarType  Amount 
------------------ 
Toyota  10000 
Honda  11000 

基本的に私はHondaのために、私に11,000値になるだろうcar.Price.Amountプロパティを、したいです。

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

が、私はCarPriceにマッピングするために、その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

ここに特別なものはありません。識別子をエンティティプロパティとして追加するだけで、外部キープロパティとして使用できます。

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(); 
     } 
    } 
} 
+0

いいえ、私は車のレベルにCarTypeを導入することはできません。 Discriminatorの列には既にHonda、Toyotaなどのタイプがあります。 –

+0

なぜ私は理解できません。モデルと制約を明確にすることはできますか? –

+0

いくつかの理由:1)テーブルに新しい列を追加することで、「アップグレード」したくない100万レコードがあります。 2)「Discriminator」列には必要な情報がすでに入っているので、必要はありません。 3)それぞれの「カスタム」識別器をエンティティにマップする必要がある「Requires」部分が嫌いです。それは必要ではありません。 –

関連する問題