Search code examples
c#entity-frameworkcode-first

Why EF tries to convert List<Type> to Type when saving an object with a list of related objects (1 to many)?


When I try to save a Consumption object by calling context.Consumption.Add(myConsumption) and then context.SaveChanges(), I get a System.InvalidCastException. I have no clue why EF wants to cast the List<Payment> to Payment, since the Payments property of Consumption is of type List<Payment>.

    public class Consumption {
       public int Id { get; set; }
       ...
       public virtual List<Payment> Payments { get; set; }
    }

    public class Payment {
       ...
       [ForeignKey("Id")]
       public Consumption Consumption { get; set; }
    }

Solution

  • I think you have things a little out of wack

    Assuming you have the following design

    public class Consumption 
    {
       public int Id { get; set; }
       ...
       public virtual List<Payment> Payments { get; set; }
    }
    
    public class Payment {
       public int Id { get; set; }
       public Consumption Consumption { get; set; }
       public int ConsumptionId { get; set; }
    }
    

    EF is smart enough to figure out the relationship and database scaffolding based on naming convention

    However if you need to use Annotations, then you need to make a decision of how you are telling EF about your relationship

    public class Payment {
       public int Id { get; set; }
       public Consumption Consumption { get; set; }
       [ForeignKey("Consumption")] // point to the FK to the navigation property
       public int ConsumptionId { get; set; }
    }
    

    Or

    public class Payment {
       public int Id { get; set; }
       [ForeignKey("ConsumptionId")] // point to the navigation property to the FK
       public Consumption Consumption { get; set; }
       public int ConsumptionId { get; set; }
    }
    

    Or

    public class Consumption 
    {
       public int Id { get; set; }
       ...
       [ForeignKey("ConsumptionId")]  // Point to the dependent FK
       public virtual List<Payment> Payments { get; set; }
    }
    

    My suspicion is that in your database (and this should be easy to check) you just have a singular foreign key in your Consumption table for payment

    You seem to be pointing to the Primary key of your Payments table. However musings aside, it surprises me that EF even let you do this migration (if i'm reading this correctly)