实体框架CodeFirst奇怪的NullReference

时间:2016-01-17 21:14:43

标签: c# entity-framework entity-framework-6

我有一个奇怪的空引用,即向我的数据库添加数据。 我在一个模型中有三个关键参考。两个关键的工作完​​美但最后...... 例如,我的简单代码优先模型:

   [Table("Users")]
public partial class User
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ClientId { get; set; }
    [StringLength(60)]
    public string ClientType { get; set; }
    [StringLength(160)]
    public string ClientName { get; set; }
    public virtual ICollection<Repair> Repairs { get; set; }
    public User()
    {
        Repairs = new List<Repair>();
    }
}
[Table("Engineers")]
public partial class Engineer
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [StringLength(70)]
    public string Name { get; set; }

    public virtual ICollection<Repair> Repairs { get; set; }
    public Engineer()
    {
        Repairs = new List<Repair>();
    }
}
[Table("CurrentStatuses")]
public partial class CurrentStatus
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int StatusId { get; set; }

    [StringLength(60)]
    public string Status { get; set; }

    public virtual ICollection<Repair> Repairs { get; set; }
    public CurrentStatus()
    {
        Repairs = new List<Repair>();
    }
}

某些数据已添加到用户,工程师和CurrentStatuses中。 在SQL Management Studio中一切都OK!这个表简单愚蠢。 实体框架可以从这些表中获取数据,将其存储在DataGrid,ComboBox等中...... 下一个主表代码优先模型:

    [Table("Repairs")]
public partial class Repair
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    [Column(TypeName = "date")]
    public DateTime Date { get; set; }
    [StringLength(255)]
    public string HardwareInfo { get; set; }
    public virtual User User { get; set; }
    public virtual Engineer Engineer { get; set; }
    public virtual CurrentStatus CurrentStatus { get; set; }
    [StringLength(140)]
    public string Info { get; set; }

}

我想添加新的“修复”: 1)获取工程师:

        public static async Task<ObservableCollection<Engineer>> GetAllEngineers()
    {
        using (var cntx = new ServiceDBContext())
        {
            ObservableCollection<Engineer> tmp = new ObservableCollection<Engineer>();
            await (cntx.Engineers.Include(xx => xx.Repairs).ForEachAsync(new Action<object>((object obj) => { tmp.Add((Engineer)obj); })));
            return tmp;

        }
    }

2)获取用户(抱歉为虚拟代码):         public static async任务&gt; GetAllUsers()         {

        using (var cntx = new ServiceDBContext())
        {
            ObservableCollection<User> tmp = new ObservableCollection<User>();
            List<User> users = await cntx.Users.ToListAsync();
            foreach (var itm in users)
            {
                tmp.Add(itm);
            }

            return tmp;
        }
    }

3)获取CurrentStatuses:

 internal static async Task<ObservableCollection<CurrentStatus>> GetAllCurrentStatuses()
    {
        using (var cntx = new ServiceDBContext())
        {
            ObservableCollection<CurrentStatus> tmp = new ObservableCollection<CurrentStatus>();
            await(cntx.CurrentStatuses.ForEachAsync(new Action<object>((object obj) => { tmp.Add((CurrentStatus)obj); })));
            return tmp;

        }
    }

4)好的!我有所有数据要写新的“修复”(所有类型都可以)。

        private void _addRepair()
    {

        FastRepair.Id =  2;
        FastRepair.Date = SelectedDate;
        FastRepair.User = SelectedUser;
        ...
        FastRepair.CurrentStatus = SelectedStatus

        using (ServiceDBContext cntx = new ServiceDBContext())
        {
            cntx.Users.Attach(FastRepair.User);
            cntx.Engineers.Attach(FastRepair.Engineer);
            cntx.CurrentStatuses.Attach(FastRepair.CurrentStatus);

            cntx.Repairs.Attach(FastRepair);
            cntx.Entry(FastRepair).State = EntityState.Added;

            cntx.SaveChanges();
        }

当我想再次获取FastRepair.CurrentStatus时,我有NullReferenceException,在数据库中所有三列都有数字,数据库有表的键。 SaveChanges()成功添加所有数据。一切正常,但实体仅在CurrentStatus 处抛出NullReference(工程师,用户表使用Including等成功获取)。

  public static async Task<ObservableCollection<Repair>> GetFullRepairs()
    {
         using (var cntx = new ServiceDBContext())
            { 

            ObservableCollection<Repair> tmp = new ObservableCollection<Repair>();
            await (cntx.Repairs.Include(xx => xx.Engineer).Include(zz=> zz.CurrentStatus).Include(yy => yy.User).ForEachAsync(new Action<object>((object obj) => { tmp.Add((Repair)obj); })));
            return tmp;
        }
    }

此时LazyLoading已禁用,但没有更改。

数据库被删除5次,重新编译,谷歌不起作用。 :( 也许有人可以帮助我! 谢谢!

2 个答案:

答案 0 :(得分:1)

在每种方法中创建上下文并不是很聪明。查看存储库模式并通过依赖注入注入上下文。你的代码几乎是不可测试的。就个人而言,如果我看到这种功能的静态方法,我会得到眼癌: - )

由于非共享上下文,可能成为一种后效。 这里使用哪个EF版本? 6? 5? 有没有为您的架构使用FluentAPI的原因?如果映射错误,流畅的符号会提供更多的错误功能和信息。

答案 1 :(得分:0)

首先,这段代码很糟糕。 不要使用静态方法 - 使用存储库模式。 答案! 此代码在GetFullRepairs()中有错误。需要工作:

(((((cntx.Repairs.Include(ee=> ee.User)).Include(xx => xx.Engineer)).Include(yy => yy.RepairStatus))