none
ForeignKey Annotations Confusing for DerivedTypes

    Question

  • I know that often EF Code First needs some help (I.e. annotations) to properly handle mapping associations to DB relationships.

    In my case I have a model of (BONDS) and their interest payments (COUPONS).    In my case, BOND is an abstract base class which I further subtyped into FixedRateBond, and FloatingRateBond etc...     

    public abstract class Bond
    
    { 
    
       public ICollection<Coupon> 
    
    }
    
    
    
    public class FixedRateBond :  Bond
    
    { }
    
    
    public class FloatingRateBond: Bond
    
    {}

    Without a reference property from the COUPON class, EF would raise an error "unable to retrieve association information .... only models that include foreign key information are supported.   To solve this, I seem to need my Coupon Class to be written as follows

    public class Coupon
    {
    public Guid FloatingRateBondId {get;Set;}
    public FloatingRateBond {get;Set;}
    
    public Guid FixedRateBondId {get;Set;}
    public FixedRateBond {get;Set;}
    
    
    
    // etc...
    
    
    
    }

    
    

    this quickly becomes unmanageable if my bond hierarchy is more complex... as an example if I were to subtype bond to 10 - 15 derived types that I'd like to support in my application, that would mean I'd have to explicitly add foreign key / reference property for each subtype and the Coupon Class would look quite messy.

    What I would like to ask is if there is anyway to benefit from the fact that all my derived bonds have a common ancestor base class BOND? in other words, Is there a way to get just have a single foreign key / reference property from the Coupon class back to the parent Bond base class

    like this ?

    public Class Coupon 
    {
    public Guid BondId {get;set;}
    public Bond Bond {get;set;}
    }
    Any guidance would be greatly appreciated..

    • Edited by DoWorkAync Saturday, June 29, 2013 11:30 AM Typo
    Saturday, June 29, 2013 11:19 AM

All replies

  • Hi DoWorkAync,

    I didn't see you have specified the Id for the entities.

    By convention, code first can specify the relationship if you have added the navigation properties.

    If I use the following code, I will create the database without any errors.

    public abstract class Bond
    {
        public Guid BondId { get; set; }
        public ICollection<Coupon> Coupons { get; set; }
    }
    public class FixedRateBond : Bond
    { }
    public class FloatingRateBond : Bond
    { }
    public class Coupon
    {
        public Guid CouponId { get; set; }
        public Guid BondId { get; set; }
        public Bond Bond { get; set; }
    }
    public class FKContext : DbContext
    {
        public DbSet<Bond> Bonds { get; set; }
        public DbSet<Coupon> Coupons { get; set; }
    }


    Best regards,

    Chester Hong
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help

    Monday, July 01, 2013 8:53 AM
    Moderator
  • Hello Chester,

    Yes, I am sorry for the omission, I forgot to mention that my BOND does in fact, inherit from an ancestor class which contains the Id field.   As I am still having the issue, I will review the code and try to submit further details about my particular case.  

    I suppose from your post above, that the answer to my question is that Entity Framework will be able to work with a model where:

    - COUPON has FOREIGN KEY to a base class BOND

    - Subtypes of BOND are those classes which have properties of type ICollection<COUPON>

    Can you confirm that ?

    Monday, July 01, 2013 9:13 AM
  • Hello,

    Further to my earlier post, I've reviewed my code, and it is possible another part of the model is causing the error.  Elsewhere in my domain m

        public interface ICouponSchedule
        {
            
            ICollection<CouponPayment> CouponPaymentSchedule { get; }
            

    and I've attempted to include a FK in the child class:

    public class ICouponPayment: EntityBase
        {
         
           public Guid CouponScheduleId { get; set; }
            public ICouponSchedule CouponSchedule{ get; set; }
        }

    I suspect EF can't deal with a FK property (Coupon Schedule) being an interface.   Am I right ?
    • Edited by DoWorkAync Monday, July 01, 2013 2:39 PM Type
    Monday, July 01, 2013 2:38 PM