daveyedgar

daveyedgar

  • 1.6k
  • 9
  • 1.2k

LINQ query in controller showing child as null in Detail view

Nov 23 2023 10:42 PM

I have a self-referencing relationship for the Contacts model, e.g. a contact can have a relationship with another contact. In the Controller GET: Details method I have this code:

var contact = await _context.Contacts
                          .Include(r => r.RelationshipsAsParent)
                            .ThenInclude(t => t.RelationshipType)
                           .FirstOrDefaultAsync(m => m.Id == id);

The debugger shows the RelationshipsAsParent.Child as null

I can get the ChildId, but there should be the "FullName" of the Contact under the child.

The GET: Index query shows it as not null, so I can access the "FullName".

 return _context.Contacts != null ?
                        View(await _context.Contacts
                        .Include(r => r.RelationshipsAsParent)
                          .ThenInclude(t => t.RelationshipType)
                        .ToListAsync()) :
                        Problem("Entity set 'ApplicationDbContext.Contacts'  is null.");

I can't figure out why the Child is null for the Details method, but not for the Index method.

Thanks in advance for any help :)



Models

public class Contact
    {
        public int Id { get; set; }

        public string? FirstName { get; set; }

        public string? LastName { get; set; }

        [NotMapped]
        public string? FullName { get { return $"{FirstName} {LastName}"; } }

        // Navigation properties for relationships where this contact is the parent
        public virtual List<Relationship>? RelationshipsAsParent { get; set; }

        // Navigation properties for relationships where this contact is the child
        public virtual List<Relationship>? RelationshipsAsChild { get; set; }
    }

public class Relationship
    {
        public int Id { get; set; }

        public int? ParentId { get; set; }
        public virtual Contact? Parent { get; set; }



        // Foreign key and navigation property for the child contact
        public int? ChildId { get; set; }
        public virtual Contact? Child { get; set; }

        // Navigation property for the relationship type (assuming there's a RelationshipType entity)
        public int? RelationshipTypeId { get; set; }
        public virtual RelationshipType? RelationshipType { get; set; }
    }

public class RelationshipType
    {
        public int Id { get; set; }
        public string? Type { get; set; }



        public virtual List<Relationship>? Relationships { get; set; } = new List<Relationship>();
    }

 

Fluent API

modelBuilder.Entity<Relationship>(b =>
            {
                modelBuilder.Entity<Relationship>()
                .HasOne(r => r.Parent)
                .WithMany(c => c.RelationshipsAsParent)
                .HasForeignKey(r => r.ParentId)
                .OnDelete(DeleteBehavior.Restrict);

                modelBuilder.Entity<Relationship>()
                .HasOne(r => r.Child)
                .WithMany(c => c.RelationshipsAsChild)
                .HasForeignKey(r => r.ChildId)
                .OnDelete(DeleteBehavior.Restrict);
            });

Detail View

<h3>Relationships</h3>
    <ul>
        @if (@Model.RelationshipsAsParent.Count > 0)
        {
            @for (int j = 0; j < Model.RelationshipsAsParent.Count; j++)
            {
                <li>@Model.RelationshipsAsParent[j].ChildId: @Model.RelationshipsAsParent[j].RelationshipType.Type</li>
            }
        }
        else
        {
            <li>No Relationships</li>
        }
    </ul>

Index View

<div class="row ms-5">
  <ul>
  @if (item.RelationshipsAsParent != null)
    {
    @for (int j = 0; j < item.RelationshipsAsParent.Count; j++)
    {
    <li>@item.RelationshipsAsParent[j].Child.FullName: @item.RelationshipsAsParent[j].RelationshipType.Type</li>
    }
    }
    else
   {
    <li>No Relationships</li>
   }
  </ul>
</div>

 


Answers (1)