简体   繁体   中英

Entity Framework returning null children, underlying SQL is fine

I'm currently having strange issues with null child values using Entity Framework connecting to a Pervasive database. I'm pretty new EF so my terminology may be wrong.

I have two classes, we'll call them Parent and Child. This is how they're set up:

public class Parent
{        
    public int ParentUK { get; set; }
    public int ParentName { get; set; }
    public int Status { get; set; }
    public virtual IList<Child> Children { get; set; }
}

With a mapping file

public class Parent_Map : SchemaNameEntityTypeConfiguration<Parent>
{
    public Parent_Map(string schemaName)
        : base(schemaName)
    {
        ToTable("Parent");
        HasKey(p => p.ParentUK);

        Property(p => p.ParentUK)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        Property(p => p.ParentName)
            .IsRequired();

        Property(p => p.Status)
            .IsRequired();

        HasMany(p => p.Children)
            .WithRequired()
            .HasForeignKey(c => c.ParentUK);
    }
}

And the Child class

public class Child
{
    public int ParentUK { get; set; }        
    public int Sequence { get; set; }
    public int ChildName { get; set; }
}

Mapping:

public class Child_Map : SchemaNameEntityTypeConfiguration<Child>
{
    public Child_Map(string schemaName)
        : base(schemaName)
    {
        ToTable("Child");

        HasKey(t => t.ParentUK);
        HasKey(t => t.Sequence);

        Property(t => t.ParentUK)
             .IsRequired();

        Property(t => t.Sequence)
             .IsRequired();

        Property(t => t.ChildName)
             .IsRequired();

     }
}

When I run the following query, I expect to get a list of 2 Parents with 3 Children each.

var result = context.Parents
     .Include(p => p.Children)
     .Where(p => p.ParentUK < 3);


foreach (var thing in result)
{
     if (thing.Children != null)
     {
          Console.WriteLine(thing.ParentName+ "  has some children " + thing.Children.Count);
     } 
     else
     {
          Console.WriteLine(thing.ParentName+ "  has NO children ");
     }
}

I've verified that the underlying SQL includes the join between the two tables and returns 6 rows.

The problem that I'm struggling with is that the first result does contain a list of children but the second result's list is null. If I run the query going after individual IDs, everything works properly so I don't know if my mapping is the problem.

If I run the query with more results, it'll be something like

P1  has some children 3
P2  has NO children
P3  has NO children
P4  has NO children
P5  has some children 3
P6  has NO children
P7  has NO children
P8  has NO children

If I run the query with lazy loading, I'll get similar results but instead P7 will have children and P5 won't.

This is a generic example but it should illustrate my problems. I'm really not sure why EF is struggling to populate the lists. It doesn't throw any exceptions but I'm not sure if it silently logs somewhere.

Try to replace...

HasKey(t => t.ParentUK);
HasKey(t => t.Sequence);

...by...

HasKey(t => new { t.ParentUK, t.Sequence });

...which is the correct way to define a composite key. In your original mapping HasKey(t => t.Sequence) overwrites HasKey(t => t.ParentUK) so that EF only considers the Sequence as the key.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM