9

Ho eseguito uno scenario in cui Entity Framework 4.0 non genera un'associazione a un'entità supportata da una tabella che ha un indice unicoe mi chiedo perché.Perché EF 4 non genera un'associazione per la relazione FK con la colonna con indice univoco?

La configurazione di base è questa: Diciamo che ho due tabelle in SQL Server 2008 R2 e una relazione chiave esterna:

CREATE TABLE [dbo].[User](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [GroupId] [int] NULL, 
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

CREATE TABLE [dbo].[Group](
[Id] [int] IDENTITY(1,1) NOT NULL, 
CONSTRAINT [PK_Group] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

ALTER TABLE [dbo].[User] WITH CHECK ADD CONSTRAINT [FK_User_Group] 
    FOREIGN KEY([GroupId]) 
REFERENCES [dbo].[Group] ([Id]) 

Inoltre, assume il seguente indice è presente:

CREATE NONCLUSTERED INDEX [IX_Group] ON [dbo].[Group] 
(
[Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 

Se dico al progettista in Visual Studio 2010 di generare un modello di dati di entità ADO.NET, ottengo un modello con due classi, User e Group, User con una proprietà di navigazione denominata Group. Va tutto bene e bene.

Ora, diciamo invece che l'indice si presentava così:

CREATE UNIQUE NONCLUSTERED INDEX [IX_Group] ON [dbo].[Group] 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 

Cioè, la cosa unica che ho fatto è rendere l'indice di un indice univoco. Fatto questo, quando dico al designer di Visual Studio di generare un Entity Model, l'associazione tra utenti e gruppi non viene visualizzata e lo User non ha proprietà di navigazione. L'ispezione del file EDMX generato rivela che il modello di archiviazione non ha affatto AssociationSet.

Qualcuno può spiegare perché questo è? Perché l'indice univoco impedisce a EF di modellare la relazione?

Grazie.

risposta

12

Un indice univoco consente 1 valore NULL, una chiave primaria non consente NULLS. Come abbinerai il NULL quando nulla è uguale a NULL nemmeno a un altro NULL

+0

Hmm, forse hai ragione, ma Linq2SQL in grado di gestire questo scenario. Inoltre, posso aggiungere manualmente gli AssociationSet appropriati nell'EDMX e funzionerà bene, quindi non capisco perché EF si arrenda. – Rune

+0

thaks uomo molto, ho perso più di 1 ora per capire perché le proprietà di navigazione non mappano, la tua risposta mi ha aiutato. grazie ancora –

1

Ho lo stesso problema. Tuttavia, nel mio caso, la colonna a cui sto tentando di collegarmi non è la chiave primaria. Quindi, non funzionerà. Il file EDMX non verrà compilato dicendo che deve collegarsi a una chiave primaria. Questo ha senso. L'unica ragione per cui mi imbatto nel problema è che ho a che fare con un database precedente mal progettato.

Tuttavia, nel tuo caso, stai creando un indice univoco su una colonna di identità. Perché? Una colonna di identità è garantita per essere unica comunque. Inoltre, è la tua chiave primaria che avrebbe un indice su di esso per impostazione predefinita.

Ho trovato questo collegamento che spiega che le associazioni ai vincoli univoci non sono attualmente supportate in EF, ma sembra che lo stiano pianificando per una versione futura.

http://blogs.msdn.com/b/efdesign/archive/2011/03/09/unique-constraints-in-the-entity-framework.aspx?wa=wsignin1.0&CommentPosted=true#commentmessage

+0

"Perché? Una colonna di identità è garantita per essere unica comunque." No, non lo è. I valori duplicati sono possibili con 'SET IDENTITY_INSERT' o con' DBCC RESEED'. – hvd

+0

Uh, sì, ma, devi fare di tutto per farlo. Quando lo fai, è intenzionale. –

+0

Ho risposto a "Una colonna di identità è garantita per essere unica comunque."Ciò significa che è impossibile ottenere valori duplicati, ma quello che ora si intende veramente è che è impossibile ottenere valori duplicati per errore. Può essere vero (non ne sono del tutto sicuro), ma è molto più debole, e se più applicazioni stanno lavorando sullo stesso database, significa che l'ipotesi che la colonna sia univoca potrebbe non essere valida, perché un altro utente su un'altra applicazione potrebbe aver intenzionalmente inserito un valore duplicato che non ti aspettavi. – hvd

Problemi correlati