using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EjemploIndices
{
public class Entrada
{
public int Identificador { get; set; }
public string Titulo { get; set; }
[Index("IndiceCalificacion")]
public int BlogId { get; set; }
}
public class Usuario
{
public int UserId { get; set; }
[Index(IsUnique = true)]
[StringLength(200)]
public string NombreUsuario { get; set; }
public string NombreVisible { get; set; }
}
public class Celda
{
public int Id { get; set; }
public string Contenido { get; set; }
[Index("IX_Posicion", 1, IsUnique = true)]
public int Fila { get; set; }
[Index("IX_Posicion", 2)]
[StringLength(5)]
public string Columna { get; set; }
}
}
La generación de la base de datos produce el siguiente esquema SQL:
CREATE TABLE [dbo].[Entradas] (
[Identificador] INT IDENTITY (1, 1) NOT NULL,
[Titulo] NVARCHAR (MAX) NULL,
[BlogId] INT NOT NULL,
CONSTRAINT [PK_dbo.Entradas] PRIMARY KEY CLUSTERED ([Identificador] ASC)
);
GO
CREATE NONCLUSTERED INDEX [IndiceCalificacion] ON [dbo].[Entradas]([BlogId] ASC);
GO
CREATE TABLE [dbo].[Usuarios] (
[UserId] INT IDENTITY (1, 1) NOT NULL,
[NombreUsuario] NVARCHAR (200) NULL,
[NombreVisible] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_dbo.Usuarios] PRIMARY KEY CLUSTERED ([UserId] ASC)
);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_NombreUsuario]
ON [dbo].[Usuarios]([NombreUsuario] ASC);
GO
CREATE TABLE [dbo].[Celdas] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Contenido] NVARCHAR (MAX) NULL,
[Fila] INT NOT NULL,
[Columna] NVARCHAR (5) NULL,
CONSTRAINT [PK_dbo.Celdas] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_Posicion]
ON [dbo].[Celdas]([Fila] ASC, [Columna] ASC);
GO
- La clase
Entradacrea un índice llamadoIndiceCalificacionen la propiedadBlogId. - En la clase
Usuario, se define un índice único sin nombre explícito; el framework genera uno con el formatoIX_NombrePropiedad. - La clase
Celdautiliza un índice compuesto enFilayColumna. Las opciones del índice, como la unicidad, se aplican en la primera propiedad del grupo.
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EjemploForaneas
{
public class BlogPrincipal
{
[Key]
public int ClavePrimaria { get; set; }
public string Titulo { get; set; }
public virtual ICollection<entradapublicacion> Publicaciones { get; set; }
}
public class EntradaPublicacion
{
public int Id { get; set; }
public string Texto { get; set; }
public int BlogPrincipalId { get; set; }
[ForeignKey("BlogPrincipalId")]
public BlogPrincipal BlogPrincipal { get; set; }
}
}</entradapublicacion>
La tabla generada incluye una restricción de clave foránea e índice:
CREATE TABLE [dbo].[BlogPrincipal] (
[ClavePrimaria] INT IDENTITY (1, 1) NOT NULL,
[Titulo] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_dbo.BlogPrincipal] PRIMARY KEY CLUSTERED ([ClavePrimaria] ASC)
);
CREATE TABLE [dbo].[EntradaPublicacion] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Texto] NVARCHAR (MAX) NULL,
[BlogPrincipalId] INT NOT NULL,
CONSTRAINT [PK_dbo.EntradaPublicacion] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.EntradaPublicacion_dbo.BlogPrincipal_BlogPrincipalId]
FOREIGN KEY ([BlogPrincipalId]) REFERENCES [dbo].[BlogPrincipal] ([ClavePrimaria])
ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_BlogPrincipalId]
ON [dbo].[EntradaPublicacion]([BlogPrincipalId] ASC);
La anotación [ForeignKey] puede aplicarse tanto a la propiedad de naveagción como a la propiedad de clave foránea. El resultado en el esquema de la base de datos es idéntico en ambos casos, ya que establece la correspondencia entre los atributos.
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EjemploInverso
{
public class Persona
{
public int Id { get; set; }
[Index(IsUnique = true)]
[StringLength(50)]
public string Nombre { get; set; }
[InverseProperty("CreadoPor")]
public List<document> DocumentosCreados { get; set; }
[InverseProperty("ActualizadoPor")]
public List<document> DocumentosActualizados { get; set; }
}
public class Document
{
public int Id { get; set; }
public string Contenido { get; set; }
public Persona CreadoPor { get; set; }
public Persona ActualizadoPor { get; set; }
}
}</document></document>
El esquema de la base de datos resultante crea las claves foráneas necesarias y sus respectivos índices:
CREATE TABLE [dbo].[Persona] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Nombre] NVARCHAR (50) NULL,
CONSTRAINT [PK_dbo.Persona] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_Nombre]
ON [dbo].[Persona]([Nombre] ASC);
CREATE TABLE [dbo].[Document] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Contenido] NVARCHAR (MAX) NULL,
[CreadoPor_Id] INT NULL,
[ActualizadoPor_Id] INT NULL,
CONSTRAINT [PK_dbo.Document] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.Document_dbo.Persona_CreadoPor_Id]
FOREIGN KEY ([CreadoPor_Id]) REFERENCES [dbo].[Persona] ([Id]),
CONSTRAINT [FK_dbo.Document_dbo.Persona_ActualizadoPor_Id]
FOREIGN KEY ([ActualizadoPor_Id]) REFERENCES [dbo].[Persona] ([Id])
);
GO
CREATE NONCLUSTERED INDEX [IX_CreadoPor_Id]
ON [dbo].[Document]([CreadoPor_Id] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_ActualizadoPor_Id]
ON [dbo].[Document]([ActualizadoPor_Id] ASC);
Entity Fraemwork nombra automáticamente las columnas de clave toánea en la tabla dependiente como NombrePropiedadNavegación_Id.