如何在添加后立即正确访问我的EF外键列?

时间:2014-09-23 11:20:26

标签: asp.net entity-framework

我的网站上有一个基本的通知系统,我已经开始使用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

1 个答案:

答案 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可能是最干净的,但它是你的号召!