尝试访问子对象时返回 Null
Null returned when trying to access child object
我正在从 Linq To Sql 迁移到 EF6,我有自动生成的对象
public partial class PCU
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public PCU()
{
this.PUs = new HashSet<PU>();
}
public int ID { get; set; }
public int FileNumberID { get; set; }
public Nullable<int> PartnerID { get; set; }
public virtual Company Company { get; set; }
public virtual File File { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PU> PUs { get; set; }
}
其中 PartnerID 是公司的外键
当我打电话时:
var company = dc.Set<PCU>().FirstOrDefault(c => c.FileNumber == fileNumber).Company;
我得到一个 Null 对象,但是如果我调用:
var company = dc.Set<PCU>().Where(c => c.FileNumber == fileNumber).Select(x => x.Company).First();
果然returns公司反对。我同时启用了 LazyLoading 和 ProxyCreation。
我知道我可以使用:
var company = dc.Set<PCU>().Include(x => x.Company).FirstOrDefault(c => c.FileNumber == fileNumber).Company;
但是,由于这是现有代码,而且我对数百个不同的对象都有同样的问题,这意味着需要进行大量更改。有没有更简单的方法来实现这个?
乍一看确实是这样的:
dc.Set<PCU>().FirstOrDefault(c => c.FileNumber == fileNumber).Company
类似于:
dc.Set<PCU>().Where(c => c.FileNumber == fileNumber).Select(x => x.Company).First()
但是如果使用 'FirstOrDefault' 时外键 'Company' 为 null,returning 'Company' 显然会 return null。
第二种情况,从'Where'条件创建的结果集中选择一个有效的'Company' FK,return是该集合中的第一个,这是为什么 'Where' 查询 return 是 'Company'.
如果您不想更改现有代码,在我看来,最好的解决方案是首先真正了解为什么您的数据库中有空外键。
如果它应该是这样的(例如,可能存在空的 'Company' 条目),那么您必须在查询中考虑到它,因此将它们更改为 return仅存在 'Company' 个条目。
编辑:我收回,我错过了'LazyLoading enabled'部分
作为跟进,我认为错误的原因是外键的名称 (PartnerID),如果它被命名为 "CompanyID" 就可以正常工作。
我只好硬着头皮执行了
var company = dc.Set<PCU>().Include(x => x.Company).FirstOrDefault(c => c.FileNumber == fileNumber).Company;
必要时。似乎没有其他解决方法,除了重命名我的数据库中的列(我不能这样做)。
我正在从 Linq To Sql 迁移到 EF6,我有自动生成的对象
public partial class PCU
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public PCU()
{
this.PUs = new HashSet<PU>();
}
public int ID { get; set; }
public int FileNumberID { get; set; }
public Nullable<int> PartnerID { get; set; }
public virtual Company Company { get; set; }
public virtual File File { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PU> PUs { get; set; }
}
其中 PartnerID 是公司的外键
当我打电话时:
var company = dc.Set<PCU>().FirstOrDefault(c => c.FileNumber == fileNumber).Company;
我得到一个 Null 对象,但是如果我调用:
var company = dc.Set<PCU>().Where(c => c.FileNumber == fileNumber).Select(x => x.Company).First();
果然returns公司反对。我同时启用了 LazyLoading 和 ProxyCreation。
我知道我可以使用:
var company = dc.Set<PCU>().Include(x => x.Company).FirstOrDefault(c => c.FileNumber == fileNumber).Company;
但是,由于这是现有代码,而且我对数百个不同的对象都有同样的问题,这意味着需要进行大量更改。有没有更简单的方法来实现这个?
乍一看确实是这样的:
dc.Set<PCU>().FirstOrDefault(c => c.FileNumber == fileNumber).Company
类似于:
dc.Set<PCU>().Where(c => c.FileNumber == fileNumber).Select(x => x.Company).First()
但是如果使用 'FirstOrDefault' 时外键 'Company' 为 null,returning 'Company' 显然会 return null。
第二种情况,从'Where'条件创建的结果集中选择一个有效的'Company' FK,return是该集合中的第一个,这是为什么 'Where' 查询 return 是 'Company'.
如果您不想更改现有代码,在我看来,最好的解决方案是首先真正了解为什么您的数据库中有空外键。
如果它应该是这样的(例如,可能存在空的 'Company' 条目),那么您必须在查询中考虑到它,因此将它们更改为 return仅存在 'Company' 个条目。
编辑:我收回,我错过了'LazyLoading enabled'部分
作为跟进,我认为错误的原因是外键的名称 (PartnerID),如果它被命名为 "CompanyID" 就可以正常工作。
我只好硬着头皮执行了
var company = dc.Set<PCU>().Include(x => x.Company).FirstOrDefault(c => c.FileNumber == fileNumber).Company;
必要时。似乎没有其他解决方法,除了重命名我的数据库中的列(我不能这样做)。