簡體   English   中英

參考導航屬性未加載(實體框架)

[英]Reference navigation property not loading (Entity Framework)

我有 3 個模型: HumanSkillHumanSkill HumanSkill之間存在多對多的關系, HumanSkill是它們之間的中介表。

我對數據庫的查詢正確加載了中間表HumanSkill的集合,但沒有加載參考導航屬性Skill ,我想通過它使用查詢加載Skill名稱( Human -> HumanSkill -> Skill -> Skill.name ) select 的投影。

public IActionResult Preview(int humanId)
{
    var currentHuman = this.db.Humans
                              .Where(x => x.Id == humanId)
                              .Select(r => new HumanPreviewViewModel
                                      {
                                          PrimaryData = r.PrimaryData,
                                          // How should I write this line?
                                          Skills = r.Skills.ToList(), 
                                      }).SingleOrDefault();

    return View(currentResume);
}

人類 model:

public class Human
{
    public Human()
    {
        this.Skills = new HashSet<HumanSkill>();
    }

    public int Id { get; set; }

    public virtual PrimaryData PrimaryData { get; set; }
    public virtual ICollection<HumanSkill> Skills { get; set; }
}

HumanSkill model:

public class HumanSkill
{
    public int Id { get; set; }

    public int HumanId { get; set; }
    public Human Human { get; set; }

    public int SkillId { get; set; }
    public Skill Skill { get; set; }
}

技能 model:

public class Skill
{
    public Skill()
    {
        this.Humans = new HashSet<HumanSkill>();
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<HumanSkill> Humans { get; set; }
}

HumanPreviewViewModel:

public class HumanPreviewViewModel
    {
        public HumanPreviewViewModel()
        {
        }
        public PrimaryData PrimaryData { get; set; }

        public List<HumanSkill> Skills { get; set; }
    }
}

如何在不使用包含的情況下實現這一目標?

如果您使用 Select 中 Skills 表中的一些數據,EF 將執行必要的連接來檢索數據

  var currentHuman = this.db.Humans
      .Where(x => x.Id == humanId)
      .Select(r => new HumanPreviewViewModel
              {
                  PrimaryData = r.PrimaryData,
                  SkillNames = r.Skills.Select(hs => hs.Skill.Name).ToList(), 
              }).SingleOrDefault();

當從實體投影到視圖 model 時,避免混合它們。 例如,沒有一個視圖 model 包含一個引用或一組實體。 雖然看起來沒有必要,但如果您想要在 HumanPreviewViewModel 中列出技能及其 ID 和名稱,則為技能創建一個可序列化視圖 model 以及 PrimaryData(如果這是另一個相關實體)。 在 PrimaryData 可能是一對一或多對一的情況下,可以將此關系中的所需屬性“展平”到視圖 model 中。

[Serializable]
public class HumanPreviewViewModel
{
    public Id { get; set; }
    public string DataPoint1 { get; set; }
    public string DataPoint2 { get; set; }

    public List<SkillViewModel> Skills { get; set; }
}

[Serializable]
public class SkillViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

然后當你 go 提取你的人類時:

var currentHuman = this.db.Humans
    .Where(x => x.Id == humanId)
    .Select(r => new HumanPreviewViewModel
    {
        Id = r.Id,
        DataPoint1 = r.PrimaryData.DataPoint1,
        DataPoint2 = r.PrimaryData.DataPoint2,
        Skills = r.Skills.Select(s => new SkillViewModel
        {
            Id = s.Skill.Id,
            Name = s.Skill.Name
        }).ToList()
    }).SingleOrDefault();

即使視圖模型和實體共享所有所需字段,您也不混合它們的原因是您的實體通常包含對更多實體的引用。 當類似於您的視圖 model 的內容被發送到序列化程序時,例如從 API 發送給客戶端,或者由於頁面調用一些看起來很無辜的東西:

var model = @Html.Raw(Json.Encode(Model));

然后序列化程序可以並且將觸摸您引用的實體中的導航屬性,這將觸發許多延遲加載調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM