C# 实体框架中的数据库查询问题。每次都是空的
我的问题是,每次尝试使用LinQ方法查询数据库时,使用C# 实体框架中的数据库查询问题。每次都是空的,c#,asp.net-mvc,entity-framework,linq,C#,Asp.net Mvc,Entity Framework,Linq,我的问题是,每次尝试使用LinQ方法查询数据库时,使用SingleOrDefault()时,我要么得到Null,要么得到invalidoOperationException 这是我的密码 var currentUser = UserManager.FindById(User.Identity.GetUserId()); var post = ApplicationDbContext.Posts .Include(c => c.Author)
SingleOrDefault()
时,我要么得到Null
,要么得到invalidoOperationException
这是我的密码
var currentUser = UserManager.FindById(User.Identity.GetUserId());
var post = ApplicationDbContext.Posts
.Include(c => c.Author)
.SingleOrDefault(c => c.Author.Id == currentUser.Id);
if (post == null)
return View(new CertainPost());
如果我在author上使用了.Include
方法,并且同时使用author值查询数据库,那么我会怀疑这是否是错误的。如果这是问题所在,我应该如何正确地书写?当加载Author
时,我能否以某种方式在代码中稍后使用SingleOrDefault()
方法?我一直这样做,但我觉得这种方式很混乱
//Such a mess
var posts = ApplicationDbContext.Posts
.Include(c => c.Author)
.ToList();
foreach(var item in posts)
{
if(item.Author.Id == currentUser.Id)
var post = ApplicationDbContext.Posts.SingleOrDefault(c=>c.Id==item.Id)
}
那么,我应该写什么代码来折衷有用性和优化呢?问题很可能是您为该作者写了多篇文章。非工作代码和工作但“混乱”的代码之间唯一有意义的逻辑区别是,在工作代码中,您是通过项目id进行选择的
Single
和SingleOrDefault
之间的区别在于,当第一个失败时,它会引发异常,而第二个将只返回null。无论哪种情况,实际上都有两种情况会使它们失败:
SingleOrDefault
提供一些其他区别细节,以便它可以匹配一篇文章,或者只需使用类似Where
的内容,并返回所有匹配的文章:
var post = ApplicationDbContext.Posts
.Include(c => c.Author)
.SingleOrDefault(c => c.Author.Id == currentUser.Id && c.Id == postId);
或
FWIW,您不需要对属于查询一部分的任何关系使用Include
。如果是作者
,则必须将其加入,以确定其id是否等于当前用户的id,因此它将已经被包括在内
此外,当您只需要id时,查找用户是不必要的查询。您已经有了id,因为您首先使用该id查找用户。您可能已经这样做了,因为直接向查询传递User.Identity.GetUserId()
将引发异常。然而,这只是因为实体框架不知道如何将该方法转换为它可以在SQL查询中执行的操作。如果只传递值,则可以:
var userId = User.Identity.GetUserId();
var posts = ApplicationDbContext.Posts
.Where(c => c.Author.Id == userId);
问题很可能是您有多个作者的帖子。非工作代码和工作但“混乱”的代码之间唯一有意义的逻辑区别是,在工作代码中,您是通过项目id进行选择的
Single
和SingleOrDefault
之间的区别在于,当第一个失败时,它会引发异常,而第二个将只返回null。无论哪种情况,实际上都有两种情况会使它们失败:
SingleOrDefault
提供一些其他区别细节,以便它可以匹配一篇文章,或者只需使用类似Where
的内容,并返回所有匹配的文章:
var post = ApplicationDbContext.Posts
.Include(c => c.Author)
.SingleOrDefault(c => c.Author.Id == currentUser.Id && c.Id == postId);
或
FWIW,您不需要对属于查询一部分的任何关系使用Include
。如果是作者
,则必须将其加入,以确定其id是否等于当前用户的id,因此它将已经被包括在内
此外,当您只需要id时,查找用户是不必要的查询。您已经有了id,因为您首先使用该id查找用户。您可能已经这样做了,因为直接向查询传递User.Identity.GetUserId()
将引发异常。然而,这只是因为实体框架不知道如何将该方法转换为它可以在SQL查询中执行的操作。如果只传递值,则可以:
var userId = User.Identity.GetUserId();
var posts = ApplicationDbContext.Posts
.Where(c => c.Author.Id == userId);
如果这有效,请尝试…
var post=ApplicationDbContext.Posts.Include(c=>c.Author.ToList().SingleOrDefault(c=>c.Author.Id==currentUser.Id)代码>不,还是一样。我觉得我不能使用。Include(c=>c.Author)
并立即在c=>c.Author.Id==currentUser.Id
中以相同的表达式请求它。我想它应该首先加载authors,然后我应该询问author Id。但问题是我不知道如何编写它,因为如果我不使用SingleOrDefault、Single或ToList(),它将返回IQueryable对象,而不是Post对象。如果您有一个引用的实体author
,那么您的Post
类中也应该有一个AuthorId
属性-否?只需使用:.SingleOrDefault(p=>p.AuthorId==currentUser.Id)
Nah,我没有authorId类,我使用了对象绑定,所以我得到了属性PublicApplicationUser Author{get;set}
,而不是public int authorId{get;set}
您的查询没有问题Include
与作为条件的内容无关,因为查询已转换为SQL。可能只是因为您正在查询的用户没有帖子。如果这样做有效,请尝试…var post=ApplicationDbContext.posts.Include(c=>c.Author.ToList().SingleOrDefault(c=>c.Author.Id==currentUser.Id)代码>不,还是一样。我觉得我不能使用。Include(c=>c.Author)
并立即在c=>c.Author.Id==currentUser.Id
中以相同的表达式请求它。我想它应该首先加载authors,然后我应该询问author Id。但问题是我不知道如何编写它,因为如果我不使用SingleOrDefault、Single或ToList(),它将返回IQueryable对象,而不是