2017-01-15 73 views
1

我有一個很難檢索從派生類C#,EF,多層次的繼承,數據將不會加載

在我的例子的數據,我想拉的方式,數據的CoatRecipe有CoastSteps,ScrubRecipes有ScrubSteps。

所有步驟都有一組輸出。

在這個例子中,數據正在保存,我可以檢索食譜,步驟,但輸出不會被檢索。我錯過了什麼?

我應該加上。在這個例子中。 Recipe1.Steps沒有OutputList。 OutputList是我想要檢索的。

我使用的EntityFramework 6.1

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Data.Entity; 
using System.Data.Entity.Migrations; 
using System.Linq; 

namespace TestApp 
{ 
    internal class Program 
    { 
     public static void Main(string[] p) 
     { 
      DeleteData(); 
      CreateRecipes(); 
      using (var db = new DbModel()) 
      { 
       var recipe1 = (from x in db.recipeDS.OfType<ScrubRecipe>() 
            .Include(x => x.steps) 
           select x).FirstOrDefault(); 

       //var recipe2 = (from x in db.recipeDS.OfType<ScrubRecipe>() 
       //     .Include(x => x.steps.OfType<ScrubStep>().Select(y => y.outputList)) 
       //    select x).FirstOrDefault(); 
      } 
     } 

     private static void DeleteData() 
     { 
      using (var db = new DbModel()) 
      { 
       db.Database.ExecuteSqlCommand("DELETE FROM [StepOutputs]"); 
       db.Database.ExecuteSqlCommand("DELETE FROM [RecipeSteps]"); 
       db.Database.ExecuteSqlCommand("DELETE FROM [Recipes]"); 
      } 
     } 

     private static void CreateRecipes() 
     { 
      // Output to be saved. 
      var stepOutput = new StepOutput(); 

      // Create a Recipe 
      var scrubRecipe = new ScrubRecipe 
      { steps = { new ScrubStep { outputList = { stepOutput } } } }; 

      // Create a Recipe 
      var coatRecipe = new CoatRecipe 
      { steps = { new CoatStep { outputList = { stepOutput } } } }; 

      // Save the Recipes 
      using (var db = new DbModel()) 
      { 
       db.scrubRecipeDS.AddOrUpdate(scrubRecipe); 
       db.coatRecipeDS.AddOrUpdate(coatRecipe); 
       db.SaveChanges(); 
      } 
     } 
    } 

    public abstract class Recipe 
    { 
     [Key] 
     public int ID { get; set; } 

     public List<RecipeStep> steps { get; set; } = new List<RecipeStep>(); 
    } 

    public class CoatRecipe : Recipe { } 

    public class ScrubRecipe : Recipe { } 

    public abstract class RecipeStep 
    { 
     [Key] 
     public int ID { get; set; } 

     public virtual Recipe recipe { get; set; } 
    } 

    public class CoatStep : RecipeStep 
    { 
     public List<StepOutput> outputList { get; set; } = new List<StepOutput>(); 
    } 

    public class StepOutput 
    { 
     [Key] 
     public int ID { get; set; } 

     public virtual RecipeStep recipeStep { get; set; } 
    } 

    public class ScrubStep : CoatStep 
    { 
     public int value { get; set; } 
    } 

    public class DbModel : DbContext 
    { 
     public DbModel() 
      : base("name=DbModelConn") 
     { 
      Database.SetInitializer(new CreateDatabaseIfNotExists<DbModel>()); 
     } 

     public virtual DbSet<Recipe> recipeDS { get; set; } 
     public DbSet<RecipeStep> recipeStepDS { get; set; } 
     public DbSet<StepOutput> stepOutputDS { get; set; } 

     public virtual DbSet<ScrubRecipe> scrubRecipeDS { get; set; } 
     public virtual DbSet<ScrubStep> scrubRecipeStepDS { get; set; } 
     public virtual DbSet<CoatRecipe> coatRecipeDS { get; set; } 
     public virtual DbSet<CoatStep> coatRecipeStepsDS { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      modelBuilder.Entity<ScrubStep>() 
       .HasMany(x => x.outputList) 
       .WithRequired(x => (ScrubStep)x.recipeStep); 



     } 
    } 
} 
+0

你是什麼意思不能檢索它?結果爲空? – esiprogrammer

+0

Outputs集合將不會填充。食譜和步驟。 – MIJ1974

+0

如果您在配方中放置一箇中斷,您會看到配方已加載,並且該步驟也是如此。我無法想出一個包含輸出的方法,因爲步驟集合構成了一個基類。 – MIJ1974

回答

1

在使用父類RecipeStep不包含您需要的集合,你將不得不使用explicit loading加載集合。您還需要將每個RecipeStep轉換爲包含該集合的子類。

foreach (var coatStep in recipe1.steps.OfType<CoatStep>()) 
{ 
    db.Entry(coatStep).Collection(x => x.outputList).Load(); 
} 

該執行的性能不會是最好的,因爲它會導致數據庫查詢每次迭代。但是,除非你有非常多的實體,否則它不應該太糟糕。

+0

'steps'沒有'outputlist'屬性。 – esiprogrammer

+0

它不會讓我包含outputList,因爲這些步驟是基本類型的,而不是來自派生類,這正是我需要的。 – MIJ1974

+0

這對CoatStep非常有用,但與ScrubStep無關。我相信我遇到的ScrubStep是一個不同的問題。更多的設計問題。我通過創建一個擁有共享輸出的中間類來解決它。 謝謝@Matt Rowland你已經從瘋狂的抽搐中治癒了我的眼睛。 – MIJ1974