Null возвращается при попытке доступа к дочернему объекту - PullRequest
0 голосов
/ 08 июля 2019

Я в процессе миграции на EF6 из Linq To 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;

однако, поскольку это существующий код, и у меня та же проблема с сотнями различных объектов, это будет означать огромное количество изменений.Есть ли более простой способ добиться этого?

Ответы [ 2 ]

0 голосов
/ 09 июля 2019

В качестве продолжения я считаю, что причиной ошибки является имя ForeignKey (PartnerID), и если бы оно было названо "CompanyID", оно бы работало нормально.

Я должен был укусить пулю, и должен был реализовать

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

где необходимо. Кажется, нет другого обходного пути, кроме переименования столбцов в моей БД (что я не могу сделать).

0 голосов
/ 08 июля 2019

Сначала это действительно выглядит так:

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».

Во втором случае выбирается действительный FK «Company» из набора результатов, созданного условием «Where», и возвращается первый из этого набора, поэтому запрос «Where» возвращает «Company» .

Если вы не хотите изменять существующий код, мне кажется, что лучшим решением для вас будет на самом деле понять, почему у вас в базе данных есть нулевые внешние ключи.

Если это так, как и должно быть (например, может существовать нулевая запись «Компания»), то вам придется учитывать это в своих запросах, следовательно, изменяя их так, чтобы они возвращали только существующие записи «Компании».

Редактировать : Я забираю его обратно, я пропустил часть 'LazyLoading включена' ?

...