我有一个奇怪的空引用,即向我的数据库添加数据。 我在一个模型中有三个关键参考。两个关键的工作完美但最后...... 例如,我的简单代码优先模型:
[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次,重新编译,谷歌不起作用。 :( 也许有人可以帮助我! 谢谢!
答案 0 :(得分:1)
在每种方法中创建上下文并不是很聪明。查看存储库模式并通过依赖注入注入上下文。你的代码几乎是不可测试的。就个人而言,如果我看到这种功能的静态方法,我会得到眼癌: - )
由于非共享上下文,可能成为一种后效。 这里使用哪个EF版本? 6? 5? 有没有为您的架构使用FluentAPI的原因?如果映射错误,流畅的符号会提供更多的错误功能和信息。
答案 1 :(得分:0)
首先,这段代码很糟糕。 不要使用静态方法 - 使用存储库模式。 答案! 此代码在GetFullRepairs()中有错误。需要工作:
(((((cntx.Repairs.Include(ee=> ee.User)).Include(xx => xx.Engineer)).Include(yy => yy.RepairStatus))