实体框架Include()不起作用

Dis*_*ile 45 c# entity-framework entity-framework-4

我有以下EF查询:

TestEntities db = new TestEntities();
var questions = from q in db.Questions.Include("QuestionType")
                from sq in db.SurveyQuestions
                where sq.Survey == surveyTypeID
                orderby sq.Order
                select q;

foreach( var question in questions ) {
    // ERROR: Null Reference Exception
    Console.WriteLine("Question Type: " + question.QuestionType.Description);
}
Run Code Online (Sandbox Code Playgroud)

当我访问QuestionType属性时,我得到一个空引用异常.我正在使用Include("QuestionType"),但它似乎不起作用.我究竟做错了什么?

编辑:当我启用了延迟加载时,它不会抛出空引用异常.

编辑:当我执行以下操作时,Include()似乎正在工作:

var questions = db.Questions.Include("QuestionType").Select(q => q);
Run Code Online (Sandbox Code Playgroud)

当我在一个单独的实体上进行谓词时,Include似乎失败了.使用Include时是不允许的?我的查询怎么样导致这个东西不起作用?

Sla*_*uma 55

问题可能与Linq表达式中的子查询有关.子查询,分组UND预测可能导致预先加载与Include默默的失败,因为提到这里,并详细解释这里(见迭戈维加的答案在线程的中间位置).

虽然我无法确定您违反了Include在这些帖子中所述使用时遵循的任何规则,但您可以尝试根据建议更改查询:

var questions = from q in db.Questions
                from sq in db.SurveyQuestions
                where sq.Survey == surveyTypeID
                orderby sq.Order
                select q;

var questionsWithInclude = ((ObjectQuery)questions).Include("QuestionType");

foreach( var question in questionsWithInclude ) {
    Console.WriteLine("Question Type: " + question.QuestionType.Description);
}
Run Code Online (Sandbox Code Playgroud)

(或使用帖子中提到的扩展方法.)

如果我正确理解链接的帖子,这并不一定意味着它现在可以工作(可能不是),但是你会得到一个例外,为你提供有关问题的更多细节.

  • 这很有效.我不得不把它作为ObjectQuery <Question>进行投射,但之后就可以了. (4认同)
  • 尼斯,只是作为一个加法:`VAR问题=(从平在db.SurveyQuestions其中sq.Survey == surveyTypeID排序依据sq.Order选择q.Question).INCLUDE("QuestionType");`可能是一点点清洁. (4认同)

Akl*_*kli 24

添加"System.Data.Entity",您就可以在IQueryable上调用Include:

var questions = from q in db.Questions
                from sq in db.SurveyQuestions
                where sq.Survey == surveyTypeID
                orderby sq.Order
                select q;

questions = questions.Include("QuestionType");
Run Code Online (Sandbox Code Playgroud)

请参阅:如何将DBQuery <T>转换为ObjectQuery <T>?

  • 为了更好地使用,可以在该命名空间中使用Include扩展方法来全部删除字符串文字:questions.Include(q => q.QuestionType); (10认同)

小智 17

错误是using System.Data.Entity在应该使用 的时候使用了using Microsoft.EntityFrameworkCore


par*_*ent 5

我遇到了Include(e => e.NavigationProperty)无法正常工作的问题,但是解决方案与上面的有所不同。

有问题的代码如下:

    UserTopic existingUserTopic = _context.UserTopics
            .Include(ut => ut.Topic)
            .FirstOrDefault(t => t.UserId == currentUserId && t.TopicId == topicId);

        if (existingUserTopic != null)
        {
            var entry = _context.Entry(existingUserTopic);
            entry.State = EntityState.Deleted;

            if (existingUserTopic.Topic.UserCreated) 
            {
                var topicEntry = _context.Entry(existingUserTopic.Topic);
                entry.State = EntityState.Deleted;
            }

            await _context.SaveChangesAsync();
        }
Run Code Online (Sandbox Code Playgroud)

因此,问题在于代码的顺序。实体标记为时,实体框架似乎使内存中的导航属性无效EntityState.Deleted。因此,要访问existingUserTopic.Topic我的代码,必须在标记为existingUserTopic已删除之前进行此操作。