我在写一个电子邮件系统,我们有一个用户表" tblUsers"和一张消息表。用户可以在他或她的收件箱中收到许多消息(来自tblusers中的其他用户)(一个:多个)。
在tblUsers表中,我有一个名为ImageURL(string)的列,其中包含用户头像的URL。在这种情况下,我循环浏览属于用户的收件箱中的邮件以及我尝试做的是,一旦收到邮件,将树向上走到tblUser并获取值该邮件所有者的ImageURL列标记为" SenderAvatar"下面。
这是我尝试过的。问题是,下面的SenderAvatar的sub linq抛出了一个nullpointer异常,即使我已经确认ImageURL有一个值(这是dev,所以只有三个用户)。不知怎的,我的逻辑和linq的逻辑在这里不一致。有人可以帮忙吗?谢谢!
修改
我发现了两个漏洞。第一个错误Dzienny
指出了我正在比较苹果和橙子的正确方向。第二个错误是FromUserId = ux.tblUserId,
,我将当前用户ID设置为FromUserId
个人,感谢您对此的所有帮助。
public List<UserInboxMsg> GetUserInboxMsg(IKASLWSEntities conx, int userid)
{
var u = (from m in conx.tblUsers where m.Id == userid select m).FirstOrDefault();
if (u != null)
{
return (from ux in u.tblInboxes
orderby ux.CreationTS descending
select new UserInboxMsg
{
CreationTS = ux.CreationTS,
ExpirationDate = ux.ExpirationDate,
FromUserId = ux.tblUserId,
HasImage = ux.HasImage,
ImageId = ux.ImageId ?? 0,
IsDeleted = ux.IsDeleted,
IsRead = ux.IsRead,
MsgId = ux.Id,
MsgSize = ux.MessageSize,
ParentId = ux.ParentId,
Title = ux.Title,
ToUserId = userid,
FromUserName = ux.Title,
SenderAvatar = conx.tblMessages.Where(mu=>mu.Id == ux.Id).FirstOrDefault().tblUser.ImageURL,
Message = ux.Message
}).ToList<UserInboxMsg>();
}
else
{
return new List<UserInboxMsg>();
}
}
}
答案 0 :(得分:1)
试试这个。
public List<UserInboxMsg> GetUserInboxMsg(IKASLWSEntities conx, int userid)
{
var u = (from m in conx.tblUsers where m.Id == userid select m).FirstOrDefault();
if (u != null && conx != null)
{
return (from ux in u.tblInboxes
orderby ux.CreationTS descending
select new UserInboxMsg
{
...
...
SenderAvatar = conx.tblMessages.Any(mu=>mu.Id == ux.Id) ? (conx.tblMessages.First(mu=>mu.Id == ux.Id).tblUser != null? conx.tblMessages.First(mu=>mu.Id == ux.Id).tblUser.ImageURL : null) : null,
Message = ux.Message
}).ToList<UserInboxMsg>();
}
else
{
return new List<UserInboxMsg>();
}
}
}
如果您为Avatar获取null,则要么是因为tblMessages中没有mu.Id等于ux.Id或tblMessage条目,但tblUser属性为null
答案 1 :(得分:1)
如果在实体框架中,两个表之间有一个外键引用,你可能会这样做:
"allFrames": true
答案 2 :(得分:1)
这里有几个问题。
第一个是第二个语句在内存中执行,而可以使整个查询以SQL运行:
from u in conx.tblUsers where m.Id == userid
from ux in u.tblInboxes
orderby ux.CreationTS descending
select new UserInboxMsg
{
CreationTS = ux.CreationTS,
ExpirationDate = ux.ExpirationDate,
FromUserId = ux.tblUserId,
HasImage = ux.HasImage,
ImageId = ux.ImageId ?? 0,
IsDeleted = ux.IsDeleted,
IsRead = ux.IsRead,
MsgId = ux.Id,
MsgSize = ux.MessageSize,
ParentId = ux.ParentId,
Title = ux.Title,
ToUserId = userid,
FromUserName = ux.Title,
SenderAvatar = conx.tblMessages.Where(mu => mu.Id == ux.Id)
.FirstOrDefault().tblUser.ImageURL,
Message = ux.Message
}
这有三个好处:
其次,不太重要的是,您应该使用Inbox.Messages
之类的导航属性,而不是加入(排序)收件箱及其消息。这使得您使用错误的连接变量的可能性降低,并且会压缩您的代码:
SenderAvatar = ux.Messages.
.FirstOrDefault().User.ImageURL,
现在如果没有头像,那么 没有头像。并且没有空引用异常。
(顺便说一句,你可以看到我讨厌类和属性名称中的这些前缀。)
答案 3 :(得分:1)
我只能猜测你的代码部分是错误的:SenderAvatar = conx.tblMessages.Where(mu=>mu.Id == ux.Id).FirstOrDefault().tblUser.ImageURL
我想你应该使用(mu =&gt; mu.UserId == ux.Id)而不是(mu =&gt; mu.Id == ux.Id)。在您的代码中,您将表的“Id”与另一个表的“Id”进行比较,该表通常在一对多关系中是错误的。 (仅适用于一对一的关系)
我说我可以猜到,因为您没有提及有关 tblInboxes 和 tblMessages 字段的任何信息。如果您可以向我提供有关其结构的更多信息,我可以更详细地回答。
顺便提一下您的代码可以使用:
var u = conx.tblUsers.FirstOrDefault(m=>m.Id == userid);
而不是
var u = (from m in conx.tblUsers where m.Id == userid select m).FirstOrDefault();
OR
conx.tblMessages.FirstOrDefault(mu=>mu.Id == ux.Id)
而不是
conx.tblMessages.Where(mu=>mu.Id == ux.Id).FirstOrDefault()