简体   繁体   中英

Entity Framework 1:0..1 (One to zero or one) relationship using Data Annotations

Trying to do something that I believe should be simple.

Customer
------
CustId
BillingId 
ShippingId 
...other customerInfo

Address
------
Id
...other addressinfo

I have the corresponding POCOs

public class Customer {
    [Key]
    public int CustId {get;set;}

    [Column("BillingId")]
    [ForeignKey("BillingAddress")
    public int? BillingId {get;set;}
    public virtual Address BillingAddress{get;set;}

    [Column("ShippingId")]
    [ForeignKey("ShippingAddress")
    public int? ShippingId {get;set;}
    public virtual Address ShippingAddress{get;set;}

    ...others...
}

public class Address {
    [Key]
    public int AddressId{get;set}

    ... others...
}

The BillingId and ShippingId are nullable because the customer may or may not have set an address yet. I'd assume with EF that if the values are null, the ShippingAddress and BillingAddress values should also be null . When I take a look at the object I'm getting back when running the application, all of the data on my Customer object is set but on the ShippingAddress / BillingAddress fields, in debug mode when I inspect the object, I get the below error:

BillingAddress = '((System.Data.Entity.DynamicProxies.CustomerD_E865AA67CAAA399D4F193A2439775301DFD2F05115619BC048699B20BF6F7B11)details).BillingAddress' 
threw an exception of type 'System.InvalidOperationException'

A same error appears for the ShippingAddress field. The application actually continues to run, the exception only gets thrown when inspecting in debug more. For the particular inspected object, the ShippingId and BillingId are populated correctly.

Not sure why this is happening given my setup.

one possible reason is: your repository is registered as singleton in DI configure.

another possible reason: add ForeignKey and InverseProperty to navigation properties

public class Customer {
    [Key]
    public int CustId {get;set;}

    //[Column("BillingId")]//not necessary if real column is same as property
    public int? BillingId {get;set;}

    [ForeignKey("BillingId")]
    [InverseProperty("Customer")]
    public Address BillingAddress{get;set;} //no need to be virtual

    //[Column("ShippingId")]
    public int? ShippingId {get;set;}

    [ForeignKey("ShippingId")]
    [InverseProperty("Customer")]//InverseProperty: Specifies the inverse of a navigation property that represents the other end of the same relationship.
    public Address ShippingAddress{get;set;} //no need to be virtual

    ...others...
}

try Scaffold-DbContext in a new project to validate your pocos:

https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/powershell#scaffold-dbcontext

Scaffold-DbContext "your connection string" -DataAnnotations -OutputDir "Models" -Force

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM