2015-06-02 39 views
0

難以解決如何僅將實體框架中的基類映射到我的數據庫,同時阻止任何有關繼承它的類的信息映射到數據庫的信息。只在實體框架中映射基類

我創建了一個簡單的示例來突出顯示我的難度,其中有一個基類Worker類和一個子類名爲Engineer。出於某種原因,假定我不在意存儲工程師的詳細信息......我只希望我的數據庫包含Worker類中的信息。

所以我做了以下內容:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Engineer e = new Engineer(); 
     e.Name = "George"; 
     e.Focus = "Software"; 

     MyDatabase db = new MyDatabase(); 
     e.Save(db); 
    } 
} 

public class MyDatabase : DbContext 
{ 
    public DbSet<Worker> Workers { get; set; } 
    public MyDatabase() : base("mytempdb") { } 
} 

[NotMapped] 
public class Engineer : Worker 
{ 
    public string Focus { get; set; } 
} 


public class Worker 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public bool Save(MyDatabase db) 
    { 
     try 
     { 
      if (db.Workers.Any(w => w.ID == this.ID)) 
      { 
       db.Workers.Attach(this); 
       db.Entry(this).State = System.Data.Entity.EntityState.Modified; 
      } 
      else 
      { 
       db.Workers.Add((Worker)this); 
      } 
      db.SaveChanges(); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e); 
      return false; 
     } 

     return true; 
    } 
} 

我做的「數據庫優先」的設計,和我的數據庫表如下所示:

CREATE TABLE [dbo].Workers 
(
    [ID] INT NOT NULL PRIMARY KEY, 
    [Name] NVARCHAR(200) NULL, 
    [Discriminator] NVARCHAR(200) NULL 
) 

然而,當我運行我的程序,它仍然在尋找一個存儲Engineer的實體。我已經告訴它不要映射它,希望它只映射基類到數據庫:

System.InvalidOperationException:無法找到EntityType'ConsoleApplication10.Engineer'的映射和元數​​據信息。

回答

1

我想你可能有保存,這樣實體框架不找對象的子類型 - Engineer之前的實體映射到一個新的Worker實體。

例如:

public class Worker 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public static FromWorker(Worker worker) 
    { 
     // example of mapping the entity 
     return new Worker 
     { 
      ID = worker.ID, 
      Name = worker.Name, 
     }; 
    } 

    public bool Save(MyDatabase db) 
    { 
     try 
     { 
      Worker worker = Worker.FromWorker(this); 

      if (db.Workers.Any(w => w.ID == worker.ID)) 
      { 
       db.Workers.Attach(worker); 
       db.Entry(worker).State = System.Data.Entity.EntityState.Modified; 
      } 
      else 
      { 
       db.Workers.Add(worker); 
      } 

      db.SaveChanges(); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e); 
      return false; 
     } 

     return true; 
    } 
} 
+0

感謝您的解決方案!我認爲這比Phil提出的解決方案要乾淨一些,因爲我不必將每個繼承類都標記爲忽略。缺點是我必須映射所有的屬性並創建這個「克隆構造函數」。沒問題。我會看到在接下來的一個小時左右,其他建議的解決方案會出現。如果沒有更好的,我會接受你的解決方案! – gnychis

+0

@gnychis必須將屬性映射出來絕對不是好事;然而,這實際上是一個ViewModel進入模型的過程,所以它不會太糟糕。也許有更好的方法。 –

+0

@gnychis順便說一句,你仍然總是需要'[NotMapped]'屬性或流利的api等價物,以便實體框架不會拋出錯誤。 –

0

編輯:你已經在使用[NotMapped]
我沒有看到,第一次遺憾。 所以我不指望它在模型中。

對於屬性 和整個類的等效流利api選項有一個不映射屬性。

[NotMapped] 
public string BlogCode { get;set; } 

和一個POCO的上下文中

public class MyDbContext : DbContext { 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) { 

     //Tell EF not to include these in DB. Ignore these please 
     // Anthing that EF picks and generates a table for that shoudl not be persisted 
     // modelBuilder.Ignore<EFpleaseIgnoreMe>(); 
     modelBuilder.Ignore<YourType>(); 
    } 
    } 
+0

糾正我,如果我錯了,但不是' modelBuilder.Ignore ()'相當於他已經在'Engineer'上擁有的'NotMapped'屬性? –

+0

@大衛,它可能是等效的是的。我沒有使用類的屬性,只在屬性。當我第一次看時,我實際上沒有看到課堂上的屬性。 –