Domanda

I'm fine with FK names of "Table_Id" OR "TableId" in my table. But the Entity Framework SQL generator is using both.

  • Mapped associations (independent associations, FK properties visible): no underscore
  • Constrained associations (foreign key associations): underscore

This kinda seems ridiculous - from a DB perspective there's no difference between these two relationships, so having consistency here would seem obvious. I'm building Model First.

Am I doing something wrong or is there some way to fix this?


EDIT: By request, including a sample. I created a new Entity diagram and generated SQL. It validates. Here's a snapshot of the diagram and Generate Database from Model script. Note the BasketId on Apples vs. Basket_Id on Oranges. The only difference is having selected "Add foreign key properties to the 'Oranges' entity." when adding that association.

enter image description here

-- --------------------------------------------------
-- Entity Designer DDL Script for SQL Server 2005, 2008, and Azure
-- --------------------------------------------------
-- Date Created: 04/29/2013 23:38:07
-- Generated from EDMX file: C:\data\web-trunk\TestEntities.Data\TestEntities.edmx
-- --------------------------------------------------

SET QUOTED_IDENTIFIER OFF;
GO
USE [TestEntities];
GO
IF SCHEMA_ID(N'dbo') IS NULL EXECUTE(N'CREATE SCHEMA [dbo]');
GO

-- --------------------------------------------------
-- Dropping existing FOREIGN KEY constraints
-- --------------------------------------------------


-- --------------------------------------------------
-- Dropping existing tables
-- --------------------------------------------------


-- --------------------------------------------------
-- Creating all tables
-- --------------------------------------------------

-- Creating table 'Baskets'
CREATE TABLE [dbo].[Baskets] (
    [Id] int IDENTITY(1,1) NOT NULL
);
GO

-- Creating table 'Apples'
CREATE TABLE [dbo].[Apples] (
    [Id] int IDENTITY(1,1) NOT NULL,
    [BasketId] int  NOT NULL
);
GO

-- Creating table 'Oranges'
CREATE TABLE [dbo].[Oranges] (
    [Id] int IDENTITY(1,1) NOT NULL,
    [Basket_Id] int  NOT NULL
);
GO

-- --------------------------------------------------
-- Creating all PRIMARY KEY constraints
-- --------------------------------------------------

-- Creating primary key on [Id] in table 'Baskets'
ALTER TABLE [dbo].[Baskets]
ADD CONSTRAINT [PK_Baskets]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- Creating primary key on [Id] in table 'Apples'
ALTER TABLE [dbo].[Apples]
ADD CONSTRAINT [PK_Apples]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- Creating primary key on [Id] in table 'Oranges'
ALTER TABLE [dbo].[Oranges]
ADD CONSTRAINT [PK_Oranges]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- --------------------------------------------------
-- Creating all FOREIGN KEY constraints
-- --------------------------------------------------

-- Creating foreign key on [Basket_Id] in table 'Oranges'
ALTER TABLE [dbo].[Oranges]
ADD CONSTRAINT [FK_BasketOrange]
    FOREIGN KEY ([Basket_Id])
    REFERENCES [dbo].[Baskets]
        ([Id])
    ON DELETE NO ACTION ON UPDATE NO ACTION;

-- Creating non-clustered index for FOREIGN KEY 'FK_BasketOrange'
CREATE INDEX [IX_FK_BasketOrange]
ON [dbo].[Oranges]
    ([Basket_Id]);
GO

-- Creating foreign key on [BasketId] in table 'Apples'
ALTER TABLE [dbo].[Apples]
ADD CONSTRAINT [FK_BasketApple]
    FOREIGN KEY ([BasketId])
    REFERENCES [dbo].[Baskets]
        ([Id])
    ON DELETE NO ACTION ON UPDATE NO ACTION;

-- Creating non-clustered index for FOREIGN KEY 'FK_BasketApple'
CREATE INDEX [IX_FK_BasketApple]
ON [dbo].[Apples]
    ([BasketId]);
GO

-- --------------------------------------------------
-- Script has ended
-- ------------------------

È stato utile?

Soluzione

You're right, there's no difference from a Data model perspective, but there is a difference from an Object Model perspective.

When you use Foreign Key Properties, then the Foreign key ID is included in the entity, but when you don't then the foreign key is silently used. The naming is part of the Entity Framework "Convention over Configuration" policy. EF sees a property named Basket_Id and doesn't see the property in the entity, so it knows to use this id without specifically configuring it.

By contrast, when Ef sees BasketId and sees the property in the entity, then it knows to map that field to the underlying BasketId column.

Basically, EF is distinguishing between the two types of foreign key navigation by using a naming convention. You can read more about this here:

Entity Framework Navigation Property generation rules

If you want to change this behavior, you could create a custom naming convention, remove the default one, and add your custom one that names things the way you want, however it very well could cause conflicts with the other type of navigation.

Honestly, I find it a bit ironic that you want to complain about consistency when you are being inconsistent in how you define your navigational properties. Stick with one or the other if consistency is so important to you.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top