我的网站上有一个基本的通知系统,我已经开始使用SignalR实时工作,但是我在访问用户表时遇到了外键问题。
我的一个页面中有以下代码,用于生成新的通知对象
Notification NewNotification = new Notification
{
UserToId = u.UserId,
NotificationText = "some text"
};
db.Notifications.Add(NewNotification);
db.SaveChanges();
string name = NewNotification.UserFrom.DisplayName;
在最后一行,我得到System.NullReferenceException: Object reference not set to an instance of an object
当我通过SignalR将NewNotification传递给客户端并尝试访问NewNotification.UserFrom.DisplayName
时,js控制台告诉我NewNotification.UserFrom未定义。尽管我在添加通知后能够在布局页面上访问它,但仍会发生这种情况。
我的通知模型的相关部分如下
public class Notification
{
public Notification()
{
this.UserFromId = WebSecurity.CurrentUserId;
}
[Key]
public int NotificationId { get; set; }
public int UserToId { get; set; }
public int UserFromId { get; set; }
public virtual UserProfile UserTo { get; set; }
public virtual UserProfile UserFrom { get; set; }
[MaxLength]
public string NotificationText { get; set; }
}
然后我的db上下文有以下内容来设置外键关系
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Notification>()
.HasRequired(n => n.UserFrom)
.WithMany(u => u.NotificationsFrom)
.HasForeignKey(n => n.UserFromId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Notification>()
.HasRequired(n => n.UserTo)
.WithMany(u => u.NotificationsTo)
.HasForeignKey(n => n.UserToId)
.WillCascadeOnDelete(false);
}
如何在创建通知后立即访问UserFrom.DisplayName
?
答案 0 :(得分:0)
保存后很可能没有刷新您的实体。你可以
1)使用其他查询从数据存储区重新获取它。如果Notification具有某种Identity标识列,则会在NewNotification
对象上的SaveChanges()上更新它。该id可用于检索对象。 (像NewNotification = db.Notifications.Single(x => x.Id == NewNotification.Id)
2)如果您讨厌上述选项,您可以执行以下操作:
((IObjectContextAdapter)db).ObjectContext.Refresh(RefreshMode.ClientWins, NewNotification);
这将更新您的NewNotification对象。不是很漂亮,但我最近碰到了一个与此类似的问题,它对我有用。
3)因为你已经在范围内有用户ID,我会考虑做db.Users.Single(x => x.UserId == u.UserId).DisplayName
如果你想通过NewNotification对象访问用户,我个人喜欢选项2,因为你的意图变得更清楚......你想要对数据库刷新你的NewNotifications对象,你想要的是什么没有将您的对象与“#34; WIN&#34;”相匹配的客户。
我认为选项3可能是最干净的,但它是你的号召!