none
Querying nested entities of an inheritance hierarchy RRS feed

  • Question

  • This is a project using POCO and code first.

    I have 2 classes, one derived from the other to allow nested composite of any number of levels:

        public class MyObject
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
        public class MyComposite : MyObject
        {
            public ICollection<MyObject> Elements { get; set; }
        }

    I created the THP DB schema. I created 3 objects, MyComposite1 contains a child MyObject1, and MyObject2 which is not a child of a MyComposte.

    MyComposite1
        MyObject1
    MyObject2

    I saved them and the table looks correct:

    Id    Name            Discriminator    MyComposite_Id

    --------------------------------------------------
    1    MyComposite1    MyComposite        NULL
    2    MyObject1        MyObject        1
    3    MyObject2        MyObject        NULL

    Now when I query them I get a flat list of 3 elements, not nested as I expected.

    IEnumerable<MyObject> objs = context.Set<MyObject>().ToList();

    How do I get them nested? I considered recursively calling Load() for each navigation object but hope there is a easier way. Also to explicitly call Load() I'd have to first make sure the initial list contains non-child elements only. How do I filter by the generated column MyComposite_Id which is not in my POCO model?

    Thanks.

    Monday, September 19, 2011 4:42 PM

Answers

  • Hi g12006,

    Welcome!

    Please feel free to try my code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.Entity;
    
    namespace NestTPH
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var context= new MyContext())
                {
                    //context.Database.CreateIfNotExists();
                    var test = context.MyObjects.OfType<MyComposite>().FirstOrDefault();
                    context.Entry<MyComposite>(test).Collection(c => c.Elements).Load();
                }
            }
        }
        public class MyObject
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
        public class MyComposite : MyObject
        {
            public ICollection<MyObject> Elements { get; set; }
        }
        public class MyContext:DbContext
        {
            public DbSet<MyObject> MyObjects { get; set; }
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Entity<MyObject>()
                    .Map<MyObject>(m => m.Requires("Discriminator").HasValue("MyObject"))
                    .Map<MyComposite>(m => m.Requires("Discriminator").HasValue("MyComposite"));
            }
        }
    
    }
    
    

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, September 20, 2011 7:10 AM
    Moderator

All replies

  • I just noticed that the child element 'MyObject1' is actually nested under MyComposite1, but it ALSO appears as a top-level object. This is not how it was created and is very confusing because there's nothing in my POCO class to distinguish a REAL top-level object from one that's not.

     

    Monday, September 19, 2011 6:47 PM
  • Hi g12006,

    Welcome!

    Please feel free to try my code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.Entity;
    
    namespace NestTPH
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var context= new MyContext())
                {
                    //context.Database.CreateIfNotExists();
                    var test = context.MyObjects.OfType<MyComposite>().FirstOrDefault();
                    context.Entry<MyComposite>(test).Collection(c => c.Elements).Load();
                }
            }
        }
        public class MyObject
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
        public class MyComposite : MyObject
        {
            public ICollection<MyObject> Elements { get; set; }
        }
        public class MyContext:DbContext
        {
            public DbSet<MyObject> MyObjects { get; set; }
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Entity<MyObject>()
                    .Map<MyObject>(m => m.Requires("Discriminator").HasValue("MyObject"))
                    .Map<MyComposite>(m => m.Requires("Discriminator").HasValue("MyComposite"));
            }
        }
    
    }
    
    

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, September 20, 2011 7:10 AM
    Moderator
  • Hi,

    I am writing to check the status of the issue on your side. Would you mind letting us know the result of the suggestions?

    If you need further assistance, please feel free to let me know. I will be more than happy to be of assistance.

    Have a nice day.

     


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, September 26, 2011 3:14 AM
    Moderator