Base solution for your next web application
Open Closed

Referential Integrity Issue - One to One relationship #466


User avatar
0
nipunjoshi created

I have an entity called Property and another entity called Address. They both need to have corresponding tables in the database. They have a one-to-one relationship.

The Property entity has PropertyId as the field which am setting to primary key using [key] attribute in the Property class, and in the Address class am setting PropertyId as the foreign key using [key, foreign key] attribute.

Also, note that Property and Address entities are inheriting from FullAuditedEntity, which imposes int Id as the primary key as well.

When I try to run the database migration, it throws the following error:

"Multiple identity columns specified for table 'IpProperties'. Only one identity column per table is allowed."

I believe this is happening because I am specifying PropertyId as the primary key on Property entity, where it already has Id as the primary key. If I do not specify that, then I will have to use Id as the "key, foreign key" value in Address table, which then would conflict with Address table's Id field.

How should I go about coding one to one relationship when there's the Id constraint being imposed by FullAuditedEntity, and EF wants to use the PK as the FK also?

Thanks in advance for your help!

Here's the section of the code:

[Table("IpProperties")] public class Property : FullAuditedEntity {

    [Key]
    public virtual int PropertyId { get; set; }

    public virtual bool Vacant { get; set; }

    public virtual Address Address { get; set; }

}

[Table("IpAddresses")] public class Address : FullAuditedEntity {

     [Key, ForeignKey("Property")]
     public virtual int PropertyId { get; set; }

    [Required]
    [MaxLength(MaxLength)]
    public virtual string StreetNumber { get; set; }

    public virtual Property Property { get; set; }
}

3 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    I overrided Id and it worked. Here, codes:

    Entities:

    [Table("IpProperties")]
        public class Property : FullAuditedEntity
        {
            public virtual Address Address { get; set; }
    
            public virtual bool Vacant { get; set; }
        }
    
    [Table("IpAddresses")]
        public class Address : FullAuditedEntity
        {
            public const int MaxStreetNumberLength = 32;
    
            [Key, ForeignKey("Property")]
            public override int Id { get; set; }
    
            public virtual Property Property { get; set; }
    
            [Required]
            [MaxLength(MaxStreetNumberLength)]
            public virtual string StreetNumber { get; set; }
        }
    

    DbContext:

    public class EfOneToOneRelationDemoDbContext : AbpDbContext
        {
            public virtual IDbSet<Property> Properties { get; set; }
    
            public virtual IDbSet<Address> Addresses { get; set; }
    
           ...
    
        }
    

    And Seed code, as a test:

    protected override void Seed(EfOneToOneRelationDemo.EntityFramework.EfOneToOneRelationDemoDbContext context)
            {
                context.Properties.Add(
                    new Property
                    {
                        Vacant = true,
                        Address = new Address
                        {
                            StreetNumber = "42"
                        }
                    });
    
                context.SaveChanges();
            }
    

    It's properly working as I test.

  • User Avatar
    0
    hikalkan created
    Support Team

    BTW, one-to-one relation should not be used normally if you have not a good reason. Consider to merge two entities into single entity class.

  • User Avatar
    0
    nipunjoshi created

    Yep, it worked for me too. Might have been doing something wrong which is why it didn't work earlier. Thanks a lot!