我正在从Linq迁移到Sql的过程中,我有一个自动生成的对象。
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();它按预期返回公司对象。我同时启用了LazyLoading和ProxyCreation。
我知道我可以:
var company = dc.Set<PCU>().Include(x => x.Company).FirstOrDefault(c => c.FileNumber == fileNumber).Company;然而,由于这是现有的代码,而且我对数百个不同的对象也有相同的问题,这将意味着大量的更改。有更容易的方法来实现这一点吗?
发布于 2019-07-09 09:35:06
作为后续,我相信导致错误的原因是ForeignKey (PartnerID)的名称,如果它被命名为"CompanyID“,它就会工作得很好。
我不得不咬紧牙关,不得不实施
var company = dc.Set<PCU>().Include(x => x.Company).FirstOrDefault(c => c.FileNumber == fileNumber).Company;在那里的墓地。除了重命名我的DB中的列(我不能这样做)之外,似乎没有其他解决办法。
发布于 2019-07-08 12:18:40
一开始看起来确实是这样:
dc.Set<PCU>().FirstOrDefault(c => c.FileNumber == fileNumber).Company
类似于:
dc.Set<PCU>().Where(c => c.FileNumber == fileNumber).Select(x => x.Company).First()
但是,如果外键'Company‘在使用'FirstOrDefault’时为空,返回'Company‘显然会返回null。
第二种情况是从“Where”条件创建的结果集中选择一个有效的“Company”FK,然后从该集合返回第一个,这就是为什么'Where‘查询返回'Company’的原因。
如果您不想修改现有的代码,那么在我看来,最好的解决方案就是首先了解为什么数据库中有空外键。
如果这是应该的方式(例如,空的'Company‘条目可能存在),那么您将不得不在查询中考虑到它,因此将它们更改为只返回现有的'Company’条目。
编辑:我回想起来,我错过了“启用LazyLoading”的部分
https://stackoverflow.com/questions/56934113
复制相似问题