尝试访问子对象时返回Null

时间:2019-07-08 11:38:36

标签: c# entity-framework linq-to-entities lazy-loading ef-migrations

我正在从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();

它按预期返回公司对象。我同时启用了LazyLoading和ProxyCreation。

我知道我可以使用:

var company = dc.Set<PCU>().Include(x => x.Company).FirstOrDefault(c => c.FileNumber == fileNumber).Company;

但是,由于这是现有代码,并且我对数百个不同的对象也遇到相同的问题,因此这意味着需要进行大量更改。有没有更简单的方法来实现这一目标?

2 个答案:

答案 0 :(得分:0)

作为后续,我相信导致错误的原因是ForeignKey(PartnerID)的名称,如果将其命名为“ CompanyID”,它将可以正常工作。

我不得不硬着头皮,不得不执行

var company = dc.Set<PCU>().Include(x => x.Company).FirstOrDefault(c => c.FileNumber == fileNumber).Company;

必要时。除了重命名数据库中的列(我不能这样做)外,似乎没有其他解决方法。

答案 1 :(得分:-1)

一开始它确实看起来像:

dc.Set<PCU>().FirstOrDefault(c => c.FileNumber == fileNumber).Company

类似于:

dc.Set<PCU>().Where(c => c.FileNumber == fileNumber).Select(x => x.Company).First()

但是如果在使用“ FirstOrDefault”时外键“ Company”为空,则返回“ Company”显然会返回null。

第二种情况,从由“哪里”条件创建的结果集中选择有效的“公司” FK,然后从该结果集中返回第一个,这就是为什么“哪里”查询返回“公司”的原因

如果您不希望更改现有代码,那么对我来说,最好的解决方案是真正了解为什么数据库中首先有空外键。

如果这是应有的方式(例如,可能存在空的“ Company”条目),则您必须在查询中将其考虑在内,因此将其更改为仅返回现有的“ Company”条目。 / p>

编辑:我收回了,我错过了“启用LazyLoading”部分?