简体   繁体   中英

Eager loading with optional navigation property c# EF

I use eager loading with my current project and in this project I have an optional navigation property. This is the model:

public enum AnswerType
{
    Preset,
    Formula
}

public class Answer: Key
{
    public int QuestionId { get; set; }
    public int? CriteriaId { get; set; }
    [Required] [MaxLength(255)] public string Text { get; set; }
    [Required] public AnswerType Type { get; set; }
    public int Order { get; set; }
    public int Priority { get; set; }
    [MaxLength(2083)] public string Image { get; set; }

    public Criteria Criteria { get; set; }
    public Question Question { get; set; }
    public Scenario Scenario { get; set; }
    public IList<AnswerFormula> Formulas { get; set; }
    public IList<Image> Images { get; set; }
}

So an Answer can have a Criteria navigation property, but it can also be null (nullable CriteriaId ). My "includes" are grabbed like this:

public IQueryable<T> List(params string[] includes)
{
  IQueryable<T> source = (IQueryable<T>) this._dbEntitySet;
  if (includes != null)
  {
    foreach (string include in includes)
      source = source.Include<T>(include);
  }
  return source;
}

What I would like to do is something like:

public IQueryable<T> List(params string[] includes)
{
  IQueryable<T> source = (IQueryable<T>) this._dbEntitySet;
  if (includes != null)
  {
    foreach (string include in includes)
      source = source.IncludeExists(include).Include<T>(include);
  }
  return source;
}

So, if I call my List method like this:

List("Answers.Formulas");

This will work, because we always have formulas. But if I call

List("Answers.Criteria", "Answers.Formulas")

It will throw this error:

"A specified Include path is not valid. The EntityType 'Piiick.Data.Answer' does not declare a navigation property with the name 'Criteria, Answers'."

The issue is the nullable Criteria . So, I would like to change the SQL generated to check for nulls before trying to do the include.

I hope that makes sense

You are calling the method incorrectly by passing in a single include path of "Answers.Criteria, Answers.Formulas" . This comma separated string will not be parsed by Entity Framework as two distinct includes, but as a single item. That is why you are getting an error stating you don't have a navigation property called Criteria, Answers as it splits up the path by . only which gives you a path like this which clearly doesn't make sense:

"Answers"
  └─ "Criteria, Answers"
    └─ "Formulas"

Instead you need to call your method with two distinct paths, for example:

var query = List("Answers.Criteria", "Answers.Formulas");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM