Naming of enties when scaffolding SQL Server database

Hi,

I have a database with two tables named "Account" and "Contact".

There are two columns in "Account" that are foreign keys to "Contact" which are called "ContactId" and "BillingContactId".

When using EF to scaffold the DB (not Radzen), I get an "Account" class that has two properties: "Contact" and "BillingContact" that are both lists of Contact type elements.

When using Radzen Blazor Studio for this process, I get an "Account" class with properties named: "Contact" (links via BillingContactId) and "Contact1" (links to ContactId).

How can I change this naming behaviour?

The project I worked on was btw. initally created with the old Radzen. There also these Contact and Contact1 naming was used but but what I find quite strage is that in the old Radzen Contact was linked to ContactId and Contact1 to BillingContactId, so now it is reversed.

Any ideas what makes the new Radzen Blazor Studio change this order and what would me interested even more, how can I adjust the naming algorithm so that I get useful names instead of properties like "Contact1"?

Thanks for your help!

There are various options during scaffold that can be used to obtain desired naming:



Thanks a lot. I was aware of that, but these settings have no effect in my case!

If I have a table the contains two foreign keys to the same (!) table (e.g. Account table with ContactId FK and BillingContactId FK that both link to the Contact table), Radzen will always create the properties "Contact" and "Contact1" in the Account class, even if I enable EF naming conventions in the dialog.

If I do this directly with EF (not using Radzen), I get an Account class with the properties "Contact" and "BillingContact" which is what I want. So there seems to be a difference in the way Radzen creates the classes compared to pure EF.

Can you post sample SQL schema as script to test it locally?

Here you are (when scaffolding, I enabled the "Use EF naming conventions" option; the two others are disabled!):

USE [test]
GO
/****** Object:  Table [dbo].[Account]    Script Date: 06.02.2025 15:40:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Account](
 [Id] [int] IDENTITY(1,1) NOT NULL,
 [Name] [varchar](255) NULL,
 [ContactId] [int] NOT NULL,
 [BillingContactId] [int] NOT NULL,
 CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED 
(
 [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Contact]    Script Date: 06.02.2025 15:40:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Contact](
 [Id] [int] IDENTITY(1,1) NOT NULL,
 [Firstname] [varchar](255) NULL,
 [Lastname] [varchar](255) NULL,
 CONSTRAINT [PK_Contact] PRIMARY KEY CLUSTERED 
(
 [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Account]  WITH CHECK ADD  CONSTRAINT [FK_Account_BillingContact] FOREIGN KEY([BillingContactId])
REFERENCES [dbo].[Contact] ([Id])
GO
ALTER TABLE [dbo].[Account] CHECK CONSTRAINT [FK_Account_BillingContact]
GO
ALTER TABLE [dbo].[Account]  WITH CHECK ADD  CONSTRAINT [FK_Account_Contact] FOREIGN KEY([ContactId])
REFERENCES [dbo].[Contact] ([Id])
GO
ALTER TABLE [dbo].[Account] CHECK CONSTRAINT [FK_Account_Contact]
GO
 

As a result, the Account class will have "Contact" and "Contact1" properties; with pure EF core scaffolding, I get "Contact" and "BillingContact" properties which is what I prefer. I use EF 9.0.1

Thanks for your help!

I see now. EF will prefix the navigation properties with the entity name - unfortunately this is not supported at the moment by RBS - we might try to improve this by introducing new scaffold option however I cannot commit if and when exactly this will be released. We just don't want to brake the code of already scaffolded apps that are using current naming and should be very careful.

OK, I understand. Would be great to see this new option soon.

In the old Radzen, the naming was the same (like Contact and Contact1) which is generally not a problem (allthough it is not very intutive!) but what really strikes me is that the ordering has changed. While the names of the properties remain the same, the linked tables are flipped when using the new Radzen Balzor Studio scaffolding.

So old Radzen:
Contact => ContactId
Contact1 => BillingContactId

Same database now with new Radzen Balzor Studio:
Contact => BillingContactId
Contact1 => ContactId

Is there anything I can do in the code behind / partial classes to make the scaffolding behave as before or even allow me to change the names of the properties while scaffolding?

Thanks!

Unfortunately the way of retrieving database meta information in the old Radzen IDE and in the RBS are completely different and edge cases like this are possible. The old Radzen used home grown SQL script to retrieve the foreign keys and sometime the result might come in different order depending on the SQL server version. RBS on the other hand will use EF tools to retrieve FK details which is not exactly in the same order like in the old Radzen or will use different naming. For sure once the RBS naming is used it will not change depending on database server version.

Btw I was able to add such option and we will do our best to test it and release it as soon as possible:

The result:



1 Like

Hello @enchev ,

that is really great news! Looking forward to being able to use this new option!

Thanks a lot!

I have just seen that you released a new version that now does include this feature. It works as expected!

Great job and thanks for the quick implementation! :clap:

Hi @enchev

I have tested this new feature, but it encountered an error with my database. Can you check and fix the issue?

This is my test database

-- MySQL Workbench Forward Engineering

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

-- -----------------------------------------------------
-- Schema TestDB
-- -----------------------------------------------------

-- -----------------------------------------------------
-- Schema TestDB
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `TestDB` DEFAULT CHARACTER SET utf8 ;
USE `TestDB` ;

-- -----------------------------------------------------
-- Table `TestDB`.`City`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `TestDB`.`City` (
  `Id` VARCHAR(255) NOT NULL,
  `Name` VARCHAR(45) NULL,
  PRIMARY KEY (`Id`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `TestDB`.`Customer`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `TestDB`.`Customer` (
  `Id` VARCHAR(255) NOT NULL,
  `Name` VARCHAR(45) NULL,
  `BornCityId` VARCHAR(255) NULL,
  `LiveCityId` VARCHAR(255) NULL,
  PRIMARY KEY (`Id`),
  INDEX `fk_Customer_City1_idx` (`BornCityId` ASC) VISIBLE,
  INDEX `fk_Customer_City2_idx` (`LiveCityId` ASC) VISIBLE,
  CONSTRAINT `fk_Customer_City1`
    FOREIGN KEY (`BornCityId`)
    REFERENCES `TestDB`.`City` (`Id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_Customer_City2`
    FOREIGN KEY (`LiveCityId`)
    REFERENCES `TestDB`.`City` (`Id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `TestDB`.`Group`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `TestDB`.`Group` (
  `Id` VARCHAR(255) NOT NULL,
  `Name` VARCHAR(45) NULL,
  PRIMARY KEY (`Id`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `TestDB`.`GroupDetail`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `TestDB`.`GroupDetail` (
  `GroupId` VARCHAR(255) NOT NULL,
  `CustomerId` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`GroupId`, `CustomerId`),
  INDEX `fk_GroupDetail_Customer1_idx` (`CustomerId` ASC) VISIBLE,
  CONSTRAINT `fk_GroupDetail_Group1`
    FOREIGN KEY (`GroupId`)
    REFERENCES `TestDB`.`Group` (`Id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_GroupDetail_Customer1`
    FOREIGN KEY (`CustomerId`)
    REFERENCES `TestDB`.`Customer` (`Id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

We will check it however just a friendly reminder that our support is guaranteed for subscribers only. You can provide details about your license and your database at info@radzen.com.

hi @enchev

I just test with my database

"Prefix navigation property names with related entity name" will failed if my database have only Composite Primary Key with 2 field.

It work well with Composite Primary Key and extra field.