locked
Entity Framework - Inheritance - Zero to one Relationship to child object, how to map? (Fluent API) RRS feed

  • Question

  • I have a Inheritance Hierarchy where Action is parent of ActionCompleted and ActionCancelled. Order class has a zero to one ActionCompleted and ActionCancelled. I have tried TPH and TPT (even tried edmx) but unable to get Entity to understand this relationship between Order and child actions, please suggest how do I map?

    //Classes

     

    public class Order{

    public int OrderId { get; set; }

    public string Name { get; set; }

    public ActionCompleted ACO { get; set

    ; }

     

    public ActionCancelled ACA { get; set

    ; }

    }

     

    public class Action

    {

     

    public int ActionID { get; set

    ; }

     

    public DateTime ActionDT { get; set

    ; }

     

    public Order Order { get; set

    ; }

    }

     

    public class ActionCompleted : Action

    { }

     

    public class ActionCancelled : Action{ public int CancelledByPhysician { get; set; } }

    

    //Mapping

    public class EDISContext:DbContext

    {

     

    public

    EDISContext()

    :

    base("EDISContext"

    ){ }

    public DbSet<Order> Orders { get; set; }

     

    public DbSet<Action> Actions { get; set

    ; }

     

     

    protected override void OnModelCreating(DbModelBuilder

    modelBuilder){

    modelBuilder.Entity<

    Order>().ToTable("Orders"

    );

    modelBuilder.Entity<

    Action

    >().HasKey(a => a.ActionID);

    modelBuilder.Entity<

    Action>().Map(m => m.ToTable("Actions"

    ))

    .Map<

    ActionCompleted>(m => m.ToTable("ActionCompleted"

    ))

    .Map<

    ActionCancelled>(m => m.ToTable("ActionCancelled"

    ));

     

    //modelBuilder.Entity<Action>().HasRequired(a => a.Order).WithOptional().Map(m => m.MapKey("DiagOrderId"));

    modelBuilder.Entity<

    ActionCompleted>().HasRequired(a => a.Order).WithOptional().Map(m => m.MapKey("DiagOrderId"

    ));

    modelBuilder.Entity<

    ActionCancelled>().HasRequired(a => a.Order).WithOptional().Map(m => m.MapKey("DiagOrderId"

    ));

    }

    }

    Sunday, November 27, 2011 2:44 PM

All replies

  • Anyone has done anything similar to this?
    Monday, November 28, 2011 3:46 PM
  • Hi prasadKR,

    Please test the following code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.Entity;
    
    namespace ConsoleApplication17
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var db= new EDISContext())
                {
    
                    db.Database.CreateIfNotExists();
                }
            }
        }
        public class Order
        {
            public int OrderId { get; set; }
            public string Name { get; set; }
            public ActionCompleted ACO { get; set; }
            public ActionCancelled ACA { get; set; }
    
        }
    
        public class Action
        {
            public int ActionID { get; set; }
            public DateTime ActionDT { get; set; }
           // public Order Order { get; set; }
        }
    
        public class ActionCompleted : Action
        {
         
        }
        public class ActionCancelled : Action
        {
            public int CancelledByPhysician { get; set; }
          
        }
        public class EDISContext : DbContext
        {
    
    
            public DbSet<Order> Orders { get; set; }
    
            public DbSet<Action> Actions { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Order>().ToTable("Orders");
    
                modelBuilder.Entity<Action>().HasKey(a => a.ActionID);
    
                modelBuilder.Entity<Action>().ToTable("Action");
                modelBuilder.Entity<ActionCompleted>().ToTable("ActionCompleted");
                modelBuilder.Entity<ActionCancelled>().ToTable("ActionCancelled");
    
               
                modelBuilder.Entity<Order>().HasOptional(a => a.ACO).WithRequired();
                modelBuilder.Entity<Order>().HasOptional(a => a.ACA).WithRequired();
    
            }
        }
    }
    
    

    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, November 29, 2011 6:38 AM
  • Why shall I try EF creating the DB for me, If there is anything wrong in my mapping of DB or code please let me know.

    But from what I know, EF will try to put the ActionId in the Order table for the zero to one relationship. Which is not what I want.

    Its Ok if you guys can simply say that this scenario is not possible with EF, but trying to make me go round and round is not helping me at all.

    Here is the same discussion on stack overflow: http://stackoverflow.com/questions/8286366/entity-framework-inheritance-zero-to-one-relationship-to-child-object-how-t

     

    Tuesday, November 29, 2011 2:36 PM
  • Hi prasadKR,

    Sorry for my wrong direction. According to your schema for datatable, it's impossible with EF now, thanks for understanding.

    ------------------------

    TPT = “store all the data for properties on the base type in a single table, store any additional data for derived types in an extra table that has a foreign key to the base table”

    ------------------------

    For one to one relationship, you can refer these links:

    http://weblogs.asp.net/manavi/archive/2011/04/14/associations-in-ef-4-1-code-first-part-3-shared-primary-key-associations.aspx

    http://weblogs.asp.net/manavi/archive/2011/05/01/associations-in-ef-4-1-code-first-part-5-one-to-one-foreign-key-associations.aspx

    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.

    Wednesday, November 30, 2011 7:26 AM
  • I know what TPT is. I have tried everything except Table per concrete class. I have tried to do the same using EDMX also but it does not work.

    I simply cannot find a way to establish a relationship to the derived class without putting a referring/foreign key to them inside the primary/referrer table.

    I have even tried polymorphic relationship, where I add properties in the principal class(order) of type of the base/parent class (Action), but I think even that does not work, it throws a different kind of error.

    I think , the only way this can work is, I use a collection<base class> type property inside the principal(order). This may work because I have seen samples of this usage (school or coursemanager).

    I cannot believe that this is not possible?? How are we going to manage 2-3 level deep inheritance and relationships to those objects??

    Wednesday, November 30, 2011 2:55 PM
  • Below is the DB script, please let me know if there is any mapping issues.

    CREATE TABLE [dbo].[Orders](
        [OrderId] [int] IDENTITY(1,1) NOT NULL,
        [Name] [varchar](50) NULL,
    ) ON [PRIMARY]

    CREATE TABLE [dbo].[Actions](
        [ActionID] [int] IDENTITY(1,1) NOT NULL,
        [ActionDT] [datetime] NOT NULL,
        [DiagOrderID] [int] NULL,
    ) ON [PRIMARY]

    CREATE TABLE [dbo].[ActionCompleted](
        [ACID] [int] IDENTITY(1,1) NOT NULL,
        [ActionID] [int] NOT NULL,
    ) ON [PRIMARY]

    CREATE TABLE [dbo].[ActionCancelled](
        [ACAID] [int] IDENTITY(1,1) NOT NULL,
        [ActionID] [int] NOT NULL,
        [CancelledByPhysician] [int] NULL,
    ) ON [PRIMARY]

    Wednesday, November 30, 2011 3:04 PM
  • It has been two years since this question was asked. I know new versions of EF has been released. I did not use any ORM the last two years hence I did not keep up with the updates in EF. Can somebody look this and let me know if it is possible now with new version of EF?

    Question formatting is better on stack overflow:

    http://stackoverflow.com/questions/8286366/entity-framework-inheritance-zero-to-one-relationship-to-child-object-how-t

    Monday, November 25, 2013 3:11 PM