C# 实体框架Include()不工作
我有以下问题:C# 实体框架Include()不工作,c#,entity-framework,entity-framework-4,C#,Entity Framework,Entity Framework 4,我有以下问题: 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
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);
}
当我访问QuestionType属性时,我得到一个空引用异常。我正在使用Include(“QuestionType”),但它似乎不起作用。我做错了什么
编辑:当我打开延迟加载时,它不会引发空引用异常
编辑:执行以下操作时,Include()似乎起作用:
var questions = db.Questions.Include("QuestionType").Select(q => q);
当我对一个单独的实体进行谓词时,Include似乎失败了。使用Include时不允许这样做吗?我的查询会导致此问题不起作用吗?问题可能与Linq表达式中的子查询有关。子选择、分组und投影可能导致“<代码> >包含< <代码>失败的静默加载),如前面提到的和更详细地解释的(参见迭戈Vega在线程中间某个地方的答案)。 虽然我真的看不出您在使用这些帖子中描述的
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);
}
(或者使用文章中提到的扩展方法。)
如果我正确理解链接的帖子,这并不一定意味着它现在就可以工作了(可能不会),但您将得到一个异常,提供有关问题的更多详细信息。添加“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");
请参阅:我遇到了这一期的
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();
}
所以问题在于代码的顺序。一旦实体标记为
EntityState.Deleted
,实体框架就会使内存中的导航属性无效。因此,要在我的代码中访问existingUserTopic.Topic
,我必须在标记existingUserTopic
删除之前执行此操作。以下是如何在所有类型的查询中执行此操作。您不需要使用“Include”。唯一的问题是,这似乎不适用于多对多导航属性
只需将您想要的导航属性作为“虚拟”属性添加到最终结果中
(这适用于更改跟踪代理。我没有在其他情况下测试它。另外,不要指定“.AsNoTracking()”)
现在,如果您这样做,数据库将不会再次被查询
var cat1 = results.First(); // query executed here
var authorName = cat1.Books.First().Author.Name; // already loaded
由于这个问题是“实体框架包括不工作”的最热门搜索结果,我只想提及一些其他可能性,尽管它们都与@Dismissile的原始帖子无关 区分大小写 SQL Server(可能还有其他数据库平台)通常以不区分大小写的方式工作。因此,如果您有主键值ABC1,数据库将接受ABC1、ABC1、ABC1等作为有效的外键值。但是,默认情况下,.Net字符串比较区分大小写,因此即使.Include生成额外的SQL以将额外值拉入EF,如果键中存在大小写差异,它也可能无法填充子对象。本文将通过几个好的链接对此进行更深入的讨论。对主键列和外键列使用区分大小写的排序规则可以降低导致.Include失败的风险 尾随空格
这是一个导致我失去了一天的生活试图找出为什么我的.Include不工作。SQL Server(可能还有其他数据库平台)经常在字符串比较中忽略尾随空格。因此,如果您有一个主键值(不包括引号)“ABC”(一个尾随空格),数据库将接受“ABC”(一个空格)、“ABC”(无空格)、“ABC”(两个空格)等作为有效的外键值。但是,.Net字符串比较不会忽略尾随空格,因此即使.Include生成额外的SQL以将额外值拉入EF,如果键中的尾随空格存在差异,它也可能无法填充子对象。本页介绍了SQL Server的行为。我还没有制定出一个很好的策略来防止这种情况。除了仔细的数据管理之外,还包括失败,即不要让用户键入外键值-使用下拉列表,或者使用可靠的rtrim用户输入。数据库或模型中的问题和问题类型之间是否存在定义的关系?是的。当LazyLoading启用时,它将加载对象。您应该使用lambdas而不是“魔术字符串”-您需要添加“使用System.Data.Entity”-请参阅检查、双重检查、三重检查以确保您的配置设置正确!我被这件事烧坏了,我的关系指向了错误的外键,这是有效的。我不得不将其转换为ObjectQuery,但之后它就可以工作了。很好,只是作为一个补充:
var questions=(来自db.SurveyQuestions中的sq,其中sq.Survey==surveyTypeID orderby sq.Order选择q.Question)。包括(“QuestionType”)代码>可能会稍微干净一点。嗯,我正在使用这种方法,但在第一次点击时它仍然不起作用。如果在并行调用中执行相同的查询,则后续调用会起作用,但第一个调用不会起作用。这在实体框架核心(至少是v2)中不起作用。我不能向(ObjectQuery或ObjectQuery)表达我爱你。您提供的这篇文章描述了我两天来在组合Select和Include时遇到的问题。为了更好地解决这个问题,您可以使用该名称空间中的Include扩展方法来一起去掉字符串文本:questions.Include(q=>q.QuestionType);谢谢--遇到了一个非常奇怪的问题&意识到我们没有将System.Data.Entity名称空间添加到类中!!我现在正面临着这个问题。然而,我不能只是重新安排代码的顺序:/你知道有没有其他方法可以让include工作吗?我建议不要使用这种方法。除了笨重的代码结构,容易出现可读性问题;这个
var cat1 = results.First(); // query executed here
var authorName = cat1.Books.First().Author.Name; // already loaded