实体框架-MVC C#奇怪的NullReference异常

本文关键字:NullReference 异常 框架 -MVC 实体 | 更新日期: 2023-09-27 18:00:30

我遇到了一个奇怪的错误,这让我有点困惑,所以让我描绘一下:

我有一个控制器,可以用房屋评论更新数据库。如果房子不存在,它会创建一个,然后更新它。

所以这是如果房子不存在的代码:

if (checkHouse == null)
{
        var department = db.Universitys.Single(d => d.universityName == "NotSet");//make dynamic
        var hws = new House();
        hws.address1 = reviewmodelview.Address1;
        hws.address2 = reviewmodelview.Address2;
        hws.postCode = reviewmodelview.postCode;
        hws.noOfDisputes = 0;
        department.Houses.Add(hws);
        db.SaveChanges(); //created the house and saved the changes, now apply the review to it.
        var theHouse = db.Houses.Single(d => d.address1 == reviewmodelview.Address1);//findhouse
        var rvw = new Review(); //create review
        rvw.condition = reviewmodelview.condition;
        rvw.furniture = reviewmodelview.furniture;
        rvw.overall = reviewmodelview.overall;
        rvw.isApproved = false;
        rvw.review = reviewmodelview.review;
        rvw.user = User.Identity.Name;
        rvw.reviewDate = DateTime.Now;
        theHouse.Reviews.Add(rvw);
        db.SaveChanges();
}

这是房子是否存在的代码:

else
{
    var theHouse = db.Houses.Single(d => d.address1 == reviewmodelview.Address1);//findhouse
    var rvw = new Review();//create review
    rvw.condition = reviewmodelview.condition;
    rvw.furniture = reviewmodelview.furniture;
    rvw.overall = reviewmodelview.overall;
    rvw.isApproved = false;
    rvw.review = reviewmodelview.review;
    rvw.user = User.Identity.Name;
    rvw.reviewDate = DateTime.Now;
    theHouse.Reviews.Add(rvw);
    db.SaveChanges();
}

现在的问题是,如果房子存在,就会增加审查。如果房子不存在,房子会被添加到数据库中,但代码中断为:

theHouse.Reviews.Add(rvw); 

如果我把鼠标悬停在评论上,它会说它为空。错误是"对象引用未设置为对象的实例。"

然而,如果我再试一次,但这次添加了数据库中已经存在的房子的地址,并在中添加了一个断点

theHouse.Reviews.Add(rvw);

上面写着:{System.Data.Objects.DataClasses.EntityCollection<Data.Manager.Review>}

我不明白为什么评论集合对于两段相同的代码是空的!

房子的型号是这样的:

namespace Data.Manager
{
    public class House
    {
        public virtual int HouseID { get; set; }
        public virtual string postCode { get; set; }
        public virtual string address1 { get; set; }
        public virtual string address2 { get; set; }
        public virtual int noOfDisputes { get; set; } //number of disputes added by tennants
        public virtual int averageRating { get; set; }
        public virtual ICollection<Review> Reviews { get; set; }        
    }
}

如果我能解释为什么会发生这种事,我会永远爱你。

实体框架-MVC C#奇怪的NullReference异常

如果您要用ICollection<Review> Reviews创建一个新房子,您必须先初始化它,然后才能使用Reviews.Add。它适用于已存在的房屋的原因是,当加载现有房屋时,集合将被初始化并使用现有值填充。

在呼叫theHouse.Reviews.Add之前,您必须按照theHouse.Reviews = new List<Review>();的思路做一些事情。您也可以在House的构造函数中预先初始化它,以确保它在任何访问尝试之前都已初始化。

尝试在House构造函数中初始化您的评论集合

namespace Data.Manager
{
    public class House
    {
        public House()
        {
          Reviews = new List<Review>();
        }
        public virtual int HouseID { get; set; }
        public virtual string postCode { get; set; }
        public virtual string address1 { get; set; }
        public virtual string address2 { get; set; }
        public virtual int noOfDisputes { get; set; } //number of disputes added by tennants
        public virtual int averageRating { get; set; }
        public virtual ICollection<Review> Reviews { get; set; }        
    }
}

正如前面的回答所述,在向Reviews对象添加项目之前,您需要初始化它。

您可以通过只保存一次更改而不是对DB进行两次调用来使代码稍微好一点。

        if (checkHouse == null)
        {
            var department = db.Universitys.Single(d => d.universityName == "NotSet");//make dynamic
            var hws = new House();
            hws.address1 = reviewmodelview.Address1;
            hws.address2 = reviewmodelview.Address2;
            hws.postCode = reviewmodelview.postCode;
            hws.noOfDisputes = 0;
            hws.Reviews = new List<Review>();
            var rvw = new Review(); //create review
            rvw.condition = reviewmodelview.condition;
            rvw.furniture = reviewmodelview.furniture;
            rvw.overall = reviewmodelview.overall;
            rvw.isApproved = false;
            rvw.review = reviewmodelview.review;
            rvw.user = User.Identity.Name;
            rvw.reviewDate = DateTime.Now;
            hws.Reviews.Add(rvw);
            department.Houses.Add(hws);
            db.SaveChanges();
        }