0

I'm still new to the .NET especially ef core. I am having trouble defining the relationship between the entities using code first approach with existing database. I develop this using Visual Studio Code and I can't do model first approach. I have 2 tables with 1:1 relationship. To achieve the json structure below, I created 3 entities (where 1 of the entity needs to be split). Based on the relationship I defined, it complains the entity already being used. Could someone give me a pointer what I do wrong in defining the relationship?

I got the following error:

System.InvalidOperationException: Cannot use table 'dbo.unitDetailTbl' for entity type 'contact' since it is being used for entity type 'address' and potentially other entity types, but there is no linking relationship. Add a foreign key to 'contact' on the primary key properties and pointing to the primary key on another entity typed mapped to 'dbo.unitDetailTbl'.

Tables Structure (1 to 1 relationship)

  • unitInfoTbl (unitId, name)
  • unitDetailTbl (unitId, addr1, phone)
CREATE TABLE [dbo].[unitDetailTbl](
    [UnitId] [int] NOT NULL Primary Key,
    [Addr1] [varchar](250) NULL,
    [Phone][varchar](32) NULL,
    
)

GO

CREATE TABLE [dbo].[unitInfoTbl](
    [UnitId] [int] NOT NULL Primary Key,
    [Name] [varchar](250) NULL,
    Foreign Key (UnitId) REFERENCES [unitDetailTbl](UnitId)
)
GO

INSERT INTO dbo.unitDetailTbl VALUES (1,'123 East Madison','123-456-7891');
INSERT INTO dbo.unitInfoTbl VALUES (1,'Building');

GO

Expected Result

[
  {
    "unitId": 1,
    "name": "Building",
    "address": {
      "unitId": 1,
      "addr1": "123 East Madison"
    },
    "contact": {
      "unitId": 1,
      "phone": "123-456-7891"
    }
  }
]

Models

public partial class unitInfo
    {
        [Key]

        public int UnitId { get; set; }
        public string name { get; set; }

        public virtual address address { get; set;} 

        public virtual contact contact { get; set;} 
    }

public partial class contact
    {
        [Key,JsonIgnore]
        public int UnitId { get; set; }

        public string phone {get; set;}        
        
        public virtual unitInfo unitInfoContact {get;set;} 
    }
    
public partial class address
    {
        
        [Key,JsonIgnore]
        public int UnitId { get; set; }

        public string Addr1 {get; set;}
    
        public virtual unitInfo unitInfoAddress { get; set; } 
        
    }

Context

public partial class unitInfoContext : DbContext
    {
         public unitInfoContext()
        {
        }

         public unitInfoContext(DbContextOptions<unitInfoContext> options)
            : base(options)
        {
        }

        public virtual DbSet <unitInfo> getUnitInfo {get; set;}
        public virtual DbSet <address> getAddress {get; set;}
        public virtual DbSet <contact> getPhone {get; set;}


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<unitInfo>(entity =>
            {
                entity.ToTable("unitInfoTbl", "dbo");
                        
                entity.HasOne(d => d.address)
                    .WithOne(a=>a.unitInfoAddress)
                    .HasForeignKey<unitInfo>(d => d.UnitId);

                entity.HasOne(c => c.contact)
                    .WithOne(a => a.unitInfoContact)
                    .HasForeignKey<unitInfo>(d => d.UnitId);
                 
            });
            
            //The address and contact entities are using the same table            
           modelBuilder.Entity<address>(entity =>
            {
                entity.ToTable("unitDetailTbl", "dbo");

            });

            modelBuilder.Entity<contact>(entity =>
            {
                entity.ToTable("unitDetailTbl", "dbo");
                 
            });

        }
    }

I have tried creating another property in AddressId that acts as FK and mapped it in the context to unitId. It still didn't work because it's expecting unitId1 in the database. I feel I mixed both the annotation and Fluent API in the model.

Another thing, I try to hide the unitId property in the address and contact entities using the following annotations but none of them working:

  • [JsonIgnore]
  • [ScaffoldColumn(false)]
  • [Display(AutoGenerateField=false)]
wwdev
  • 13
  • 4
  • 1
    What is the "existing database" schema? Did you try reverse engineering the entity model from the database, per https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/workflows/existing-database ? – David Browne - Microsoft Aug 08 '21 at 16:52
  • This is not EF6, please tag the correct version. – Gert Arnold Aug 08 '21 at 17:26
  • Now there's no version. For EF questions tagging the exact version is very important. As for the model, if there is one table `unitDetailTbl`, what's the reason for mapping two classes to it? Note that that requires specific mapping: https://learn.microsoft.com/en-us/ef/core/modeling/inheritance#table-per-hierarchy-and-discriminator-configuration. – Gert Arnold Aug 08 '21 at 17:37
  • @Gert, The TargetFramework is net 5.0 and The Package references version to the Microsoft.EntityFrameworkCore are 5.0.8. I'll read the requires specific mapping. The reason for mapping two classes so the address and contact entities can be on the same level in the nested json as you see in the expected result. If I only use 1 classes, it will be Ex: ` [ { "unitId": 1, "name": "Building", "address": { "unitId": 1, "addr1": "123 East Madison", "phone": "123-456-7891" }, } ] ` – wwdev Aug 08 '21 at 18:56
  • @David, I included the database code part above. I downloaded VS 2019 Community and I used the entity model using ASP.NET Web Application Template so I could access ADO.Net Entity Data Model using .NET Framework 4.7.2. The Code First From Database generates the following ` modelBuilder.Entity() .HasOptional(e => e.unitInfoTbl) .WithRequired(e => e.unitDetailTbl); ` I could not get the code running yet. My apology, I don't have solid understanding .NET technologies. I'm still trying to catch up with the terminologies and concepts. – wwdev Aug 08 '21 at 19:02

0 Answers0