Search code examples
c#sql-serverentity-frameworkasp.net-core-mvcself-referencing-table

Entity Framework 7 self referencing table returning null


I'm using EF 7 (beta6-13679), in an MVC 6 web application (only dnx 4.5.1 due to requiring AD integration), with a database first approach and cannot get a self referencing table to return a value properly, I always get null when running my app, however LINQPad finds and works with the parent/children just fine. Wondering if perhaps I've got something wrong, or if maybe this is a bug in the new EF. Hoping someone can duplicate the issue, or better yet, solve it. :) Apologies for not being able to imbed images, won't allow me yet.

Here is the model:

public partial class Directories
{
    public Directories()
    {
        Directory_ACL_Entries = new HashSet<Directory_ACL_Entries>();
        Files = new HashSet<Files>();
    }

    public long Directory_ID { get; set; }
    public DateTime Created { get; set; }
    public DateTime Discovery_TS { get; set; }
    public string Hash { get; set; }
    public bool Hidden { get; set; }
    public long? Parent_Directory_ID { get; set; }
    public string Path { get; set; }

    public virtual ICollection<Directory_ACL_Entries> Directory_ACL_Entries { get; set; }
    public virtual ICollection<Files> Files { get; set; }
    public virtual Directories Parent_Directory { get; set; }
    public virtual ICollection<Directories> InverseParent_Directory { get; set; }
}

Here is the EF fluent code:

modelBuilder.Entity<Directories>(entity =>
        {
            entity.HasKey(e => e.Directory_ID);

            entity.HasIndex(e => e.Hash).HasName("UK_Directories").IsUnique();

            entity.Property(e => e.Created).HasColumnType("datetime");

            entity.Property(e => e.Discovery_TS).HasColumnType("datetime");

            entity.Property(e => e.Hash)
                .IsRequired()
                .HasMaxLength(50);

            entity.Property(e => e.Path).IsRequired();

            entity.HasOne(d => d.Parent_Directory).WithMany(p => p.InverseParent_Directory).HasForeignKey(d => d.Parent_Directory_ID);
        });

This was generated automatically using reverse engineer scaffolding with the following command:

dnx ef dbcontext scaffold "Server=serverName\SQLEXPRESS;Database=dbName;Trusted_Connection=True;" EntityFramework.MicrosoftSqlServer --outputDir Models

LINQPad showing parent value returning properly: LINQPad showing parent and children

Visual Studio Returning Null: VS returning null


Solution

  • Probably is because LinqPad is using Linq to SQL which is the default Data Context that it uses at the time of create a connection. If you want to use EF 7 in LinqPad you will need to download its driver:

    Steps

    1. Go to add connections
    2. Click on View more drivers... button enter image description here
    3. Install EF 7 driver (Works best with LINQPad 5.06 or above)
    4. Use it to establish the connection to your DB.

    Now, as @bazz pointed out, EF7 doesn't support lazy loading, so you must use eager loading via Include method to load those related entities as part of your query:

    var result=Directories.Include(d=>d.Children)...;