Entity Framework - Data Annotations
DataAnnotations se usa para configurar las classs que resaltaran las configuraciones mas comunmente necesarias. Varias aplicaciones .NET tambien entienden las anotaciones de data, como ASP.NET MVC, que permite que estas aplicaciones aprovechen las mismas anotaciones para las validaciones del lado del cliente. Los atributos DataAnnotation anulan las convenciones predeterminadas de CodeFirst.
System.ComponentModel.DataAnnotations incluye los siguientes atributos que tienen un impacto en la nulidad o el tamano de la columna.
- Clave
- Marca de tiempo
- ConcurrencyCheck
- Obligatorio
- MinLength
- MaxLength
- StringLength
System.ComponentModel.DataAnnotations.Schema incluye el siguientes atributos que tienen un impacto en el esquema de la base de data.
- Tabla
- Columna
- Índice
- ForeignKey
- NotMapped
- InverseProperty
Clave
Entity Framework se basa en cada entidad con un valor clave que utiliza para el seguimiento de entidades. Una de las convenciones de las que Code First depende es como implica que propiedad es la clave en cada una de las classs de Code First.
-
La convencion es buscar una propiedad llamada "Id " o una propiedad que combine el nombre de la class y "Id " , como "StudentId ".
-
La propiedad se asignara a una columna de clave principal en la base de data.
-
Las classs Student, Course e Inion siguen esta convencion.
Ahora suponga que la class Student usa el nombre StdntID en lugar de ID. Cuando Code First no encuentra una propiedad que coincida con esta convencion, lanzara una excepcion debido al requisito de Entity Framework que debe tener una propiedad clave. Puede utilizar la anotacion de clave para especificar la propiedad que se utilizara como EntityKey.
Echemos un vistazo al siguiente codigo para una class Student que contiene StdntID, pero no sigue la convencion Code First por defecto. Entonces, para manejar esto, se agrega un atributo de clave que lo convertira en una clave principal.
class publica Estudiante {[Clave] public int StdntID {get; juntos; } cadena publica Apellido {get; juntos; } cadena publica FirstMidName {get; juntos; } Public DateTime EnrollmentDate {get; juntos; } Inions virtuales publicos ICollection {get; juntos; }}
Cuando ejecute su aplicacion y examine su base de data en el Explorador de SQL Server, vera que la clave principal ahora es StdntID en la tabla Estudiantes.
EntidadFramework tambien admite claves compuestas. Las claves compuestas tambien son claves primarias compuestas por varias propiedades. Por ejemplo, tiene una class DrivingLicense cuya clave principal es una combinacion de LicenseNumber y IssuingCountry.
public class DrivingLicense {[Key, Column (Order = 1)] public int LicenseNumber {get; juntos; } [Clave, columna (Orden = 2)] cadena publica IssuingCountry {get; juntos; } Public DateTime Emitido {get; juntos; } Public DateTime Expires {get; juntos; }}
Cuando tiene claves compuestas, Entity Framework requiere que establezca un orden de propiedades de clave. Puede hacer esto usando la anotacion Columna para especificar un orden.
Timestamp
Code First tratara las propiedades de timestamp de la misma forma que las propiedades ConcurrencyCheck, maTambien se asegurara de que el campo de la base de data que genera el codigo primero no sea anulable.
-
Es mas comun usar campos de version de fila o marca de tiempo para la verificacion de concurrencia.
-
En lugar de utilizar la anotacion ConcurrencyCheck, puede utilizar la anotacion TimeStamp mas especifica siempre que el tipo de propiedad sea una matriz de bytes .
-
Solo puede tener una propiedad de marca de tiempo en una class determinada.
Echemos un vistazo a un ejemplo simple que agrega la propiedad TimeStamp a la class del curso -
curso de class publica {public int CourseID {obtener; juntos; } titulo de cadena publica {get; juntos; } Creditos publicos int {obtener; juntos; } [Marca de tiempo] byte publico TStamp {get; juntos; } Inions virtuales publicos ICollection {get; juntos; }}
Como puede ver en laEn el ejemplo anterior, el atributo Timestamp se aplica a la propiedad Byte de la class Course. Por lo tanto, Code First creara una columna de marca de tiempo TStamp en la tabla Cursos.
ConcurrencyCheck
La anotacion ConcurrencyCheck le permite marcar una o mas propiedades como utilizadas para la verificacion de concurrencia en la base de data cuando un usuario cambia o eliminar una entidad. Si ha trabajado con EF Designer, esto hace coincidir la configuracion ConcurrencyMode de una propiedad en Fixed.
Echemos un vistazo a un ejemplo simple de como funciona ConcurrencyCheck agregandolo al titulo de la propiedad en la class del curso.
curso de class publica {public int CourseID {get; juntos; } [ConcurrencyCheck] titulo de cadena publica {get; juntos; } Creditos publicos int {obtener; juntos; } [Marca de tiempo, Tipo de data ( "marca de tiempo ")] byte publico Marca de tiempo {get; juntos; } Iniones publicas vicarriles ICollection {get; juntos; }}
En la class del curso anterior, el atributo ConcurrencyCheck se aplica a la propiedad de titulo existente. Ahora Code First incluira la columna Titulo en el comando de actualizacion para verificar la concurrencia optimista como se muestra en el siguiente codigo.
exec sp_executesql N 'UPDATE [dbo]. [Cursos] SET [Titulo] = @ 0 WHERE (([CourseID] = @ 1) AND ([Titulo] = @ 2)) ', N ' @ 0 nvarchar (max), @ 1 int, @ 2 nvarchar (max) ', @ 0 = N ' Maths ', @ 1 = 1, @ 2 = N ' Calculus 'go
Se requiere anotacion
L ' annotation required le dice a EF que una parte requiere una propiedad circular. Echemos un vistazo a la siguiente class de Estudiante donde se agrega el ID requerido a la propiedad FirstMidName. El atributo obligatorio obligara a EF a asegurarse de que la propiedad contenga data.
class publica Estudiante {[Clave] publico int StdntID {obtener; juntos; } [Obligatorio] cadena publica Apellido {get; juntos; } [Obligatorio] cadena publica FirstMidName {get; juntos; } Public DateTime EnrollmentDate {get; juntos; } Inions virtuales publicos ICollection {get; juntos; }}
Como se ve en el ejemplo anterior, el atributo obligatorio se aplica a FirstMidName y LastName. Por lo tanto, Code First creara columnas NOT NULL FirstMidName y LastName en la tabla Estudiantes como se muestra en la siguiente imagen.
MaxLength
El atributo MaxLength le permite especificar Validaciones de propiedades adicionales. Se puede aplicar a una propiedad de cadena o matriz de una class de dominio. EF Code First establecera el tamano de una columna como se especifica en el atributo MaxLength.
Echemos un vistazo a la siguiente class del curso en la que se aplica el atributo MaxLength (24)la propiedad Titulo.
curso de class publica {public int CourseID {get; juntos; } [ConcurrencyCheck] [MaxLength (24)] cadena publica Titulo {get; juntos; } Creditos publicos int {obtener; juntos; } Inions virtuales publicos ICollection {get; juntos; }}
Cuando ejecuta la aplicacion anterior, Code First crea un titulo de columna nvarchar (24) en la tabla CourseId como se muestra en la siguiente imagen.
Cuando el usuario define el titulo que tiene mas de 24 caracteres, EF lanzara EntityValidationError.
MinLength
El atributo MinLength tambien le permite especificar propiedades y validaciones adicionales, como lo hizo con MaxLength. El atributo MinLength tambien se puede usar con el Atributo MaxLength como se muestra en el siguiente codigo.
public class Course {public int CourseID {get; ensemble;} [ConcurrencyCheck] [MaxLength (24), MinLength (5)] cadena publica Titulo {get; ensemble;} public int Credits {get; ensemble;} Inions public virtual ICollection {get; ensemble;}}
EF arrojara EntityValidationError, si establece un valor de propiedad de Titulo menor que la longitud especificada en el atributo MinLength o mayor que la longitud especificada en el atributo MaxLength.
StringLength
StringLength tambien le permite especificar validaciones de propiedades adicionales como MaxLength. La unica diferencia es que el atributo StringLength solo se puede aplicar 'a una propiedad de cadena de las classs de dominio.
curso de class publica {public int CourseID {get; ensemble;} [StringLength (24)] titulo de cadena publica { get; ensemble;} public int Credits {get; ensemble;} inions virtuales publicas ICollection {obtener; juntos; }}
Entity Framework tambien valida el valor de una propiedad para el atributo StringLength. Si el usuario define el titulo que contiene mas de 24 caracteres, EF arrojara EntityValidationError.
Tabla
Codigo predeterminado La primera convencion crea un nombre de tabla similar al nombre de la class. Si deja que Code First cree la base de data y tambien desea cambiar el nombre de las tablas que crea. Luego -
-
Puede usar Code First con una base de data existente. Pero no siempre es el caso que los nombres de las classs coincidan con los nombres de las tablas en su base de data.
-
El atributo de tabla anula esta convencion predeterminada.
-
EF Code First creara una tabla con un nombre especificado en el atributo Table para una class de dominio determinada.
Echemos un vistazo al siguiente ejemplo donde la class se llama Estudiantey por convencion, Code First asume que esto coincidira con una tabla llamada Estudiantes. Si este no es el caso, puede especificar el nombre de la tabla con el atributo Table como se muestra en el siguiente codigo.
[Table ( "StudentsInfo ")] public class Student {[Key] public int StdntID {get; juntos; } [Obligatorio] cadena publica Apellido {get; juntos; } [Obligatorio] cadena publica FirstMidName {get; juntos; } Public DateTime EnrollmentDate {get; juntos; } Inions virtuales publicos ICollection {get; juntos; }}
Ahora puede ver que el atributo Table especifica la tabla como StudentsInfo. Cuando se genera la tabla, vera el nombre de la tabla StudentsInfo como se muestra en la siguiente imagen.
No solo puede especificar el nombre de la tabla, sino que tambien puede especificar un diagrama de la pestanautilizando el atributo Table como se muestra en el siguiente codigo.
[Table ( "StudentsInfo ", Schema = "Admin ")] class publica Estudiante {[Clave] public int StdntID {get; juntos; } [Obligatorio] cadena publica Apellido {get; juntos; } [Obligatorio] cadena publica FirstMidName {get; juntos; } Public DateTime EnrollmentDate {get; juntos; } Inions virtuales publicos ICollection {get; juntos; }}
Puede ver en el ejemplo anterior, la tabla se especifica con el esquema administrativo. Ahora Code First creara la tabla StudentsInfo en el esquema de administracion como se muestra en la siguiente imagen.
Columna
Tambien es identico al atributo Tabla, pero el atributo Tabla reemplaza el comportamiento de la tabla, mientras que el atributo Columna reemplaza el comportamiento de la columna.Debe primero crea un nombre de columna similar al nombre de la propiedad. Si deja que Code First cree la base de data y tambien desea cambiar el nombre de las columnas en sus tablas. Entonces -
Echemos un vistazo al siguiente ejemplo donde la propiedad se llama FirstMidName y por convencion Code First asume que esto coincidira con una columna llamada FirstMidName.
De lo contrario, puede especificar el nombre de la columna con el atributo Column como se muestra en el siguiente codigo.
estudiante de class publica {ID int publico {get; juntos; } cadena publica LastName {get; juntos; } [Columna ( "FirstName ")] cadena publica FirstMidName {get; juntos; } public DateTime EnrollmentDate {get; juntos; } Inions virtuales publicos ICollection {get; juntos; }}
Puede ver que el atributo Columna especifica la columna como Nombre. Cuando se genera la tabla, vera el nombre de la columna FirstName como se muestra en la siguiente imagen.
Índice
El atributo Index se introdujo en Entity Framework 6.1. Si esta utilizando una version anterior, la informacion de esta seccion no se aplica.
-
Puede crear un indice en una o mas columnas usando IndexAttribute.
-
Agregar el atributo a una o mas propiedades obligara a EF a crear el indice correspondiente en la base de data al crear la base de data.
-
Los indices hacen la recuperacion de data mas rapidos y eficientes, en la mayoria de los casos.capaz o una vista con indices puede afectar negativamente al rendimiento de otras operaciones, como inserciones o actualizaciones.
-
La indexacion es la nueva caracteristica de Entity Framework que le permite mejorar el rendimiento de su aplicacion Code First al reducir el tiempo requerido para realizar consultas data de la base de data.
-
Puede agregar indices a su base de data utilizando el atributo Index y anular los valores predeterminados de Unique y Cluster para obtener el indice mas adecuado a su escenario.
-
Por defecto, el indice se llamara IX_
Echemos un vistazo Mire el siguiente codigo en el que se agrega el atributo Índice en la class del curso para los creditos.
curso de class publica {public int CourseID {get; juntos; } titulo de cadena publica {get; juntos; } [Índice] public int Credits {obtener; juntos; } Inions virtuales publicos ICollection {get; juntos; }}
Puede ver que el atributo Index se aplica a la propiedad Credits. Cuando se genera la tabla, vera IX_Credits en los indices.
De forma predeterminada, los indices no no son unicos, pero puede usar el parametro llamado IsUnique para especificar que un indice debe ser unico. El siguiente ejemplo muestra un indice unico como se muestra en el siguiente codigo.
curso public class {public int CourseID {get; set;} [Index (IsUnique = true)] public string Title {get; set;} [Index] public int Credits {get; ensemble;} Virtual public inions ICollection {get; ensemble;}}
ForeignKey
La convencion Code First se ocupara de las relaciones mas comunes en su modelo, pero hay casos en los que tiene que serayuda a cuidar. Por ejemplo, cambiar el nombre de la propiedad de clave en la class Student creo un problema con su relacion con la class inion.
Inscripcion de class publica {public int EnrollmentID {get; juntos; } public int CourseID {obtener; juntos; } public int StudentID {get; juntos; } ¿Nota publica? Grade {get; juntos; } Curso de curso virtual publico {get; juntos; } Estudiante estudiante virtual publico {get; juntos; }} class publica Estudiante {[Clave] public int StdntID {get; juntos; } cadena publica Apellido {get; juntos; } cadena publica FirstMidName {get; juntos; } Public DateTime EnrollmentDate {get; juntos; } Inions virtuales publicos ICollection {get; juntos; }}
Al generar la base de data, Code First ve la propiedad StudentID en la class Enrollment y la reconoce, por convencion, que coincide con el nombre de la class mas "ID" , como clave foranea para la class Student. Sin embargo, no hay propiedad StudentID en la class Student, pero la propiedad StdntID es la class Student.
La solucion para esto es crear una propiedad de navegacion en Enrollment y usar ForeignKey DataAnnotation para ayudar a Code First a entender como construir la relacion entre las dos classs como se muestra en el siguiente codigo.
Inscripcion de class publica {public int EnrollmentID {get; juntos; } public int CourseID {obtener; juntos; } public int StudentID {get; juntos; } ¿Nota publica? Grade {get; juntos; } Curso de curso virtual publico {get; juntos; } [ForeignKey ( "StudentID ")] Estudiante estudiante publico virtual {get; juntos; }}
Ahora puede ver que el atributo ForeignKey se aplica a la propiedad de navegacion.
NotMapped
Por defecto, las convenciones de Code First, cada pLa propiedad de un tipo de data admitido que incluye captadores y definidores se representa en la base de data. Pero este no es siempre el caso en sus aplicaciones. El atributo NotMapped anula esta convencion predeterminada. Por ejemplo, puede tener una propiedad en la class Student como FatherName, pero no es necesario almacenarla. Puede aplicar el atributo NotMapped a una propiedad FatherName para la que no desea crear una columna en la base de data, como se muestra en el siguiente codigo.
class publica Estudiante {[Clave] public int StdntID {get; juntos; } cadena publica LastName {get; juntos; } publ ic string FirstMidName {get; juntos; } Public DateTime EnrollmentDate {get; juntos; } [NotMapped] public int FatherName {get; juntos; } Inions virtuales publicos ICollection {get; juntos; }}
Puede ver que el atributo NotMapped se aplica a la propiedadCamiseta FatherName. Cuando se genera la tabla, vera que la columna FatherName no se creara en una base de data, pero esta presente en la class Student.
Code First no creara una columna para una propiedad, que no tiene getters ni establecedores como se muestra en el siguiente ejemplo de las propiedades Address y Age de la class Student.
InverseProperty
InverseProperty se usa cuando tienes multiples relaciones entre classs. En class Inion, es posible que desee realizar un seguimiento de quien se inscribio en el curso actual y el curso anterior. Agreguemos dos propiedades de navegacion para la class de inscripcion.
public class Enrollment {public int EnrollmentID {get; ensemble;} public int CourseID {get; ensemble;} public int StudentID {get; ensemble;} ¿Grado publico? Grado {get; ensemble;} Curso virtual public CurrCourse {obtener; juntos; } Curso virtual publico PrevCourse {get; juntos; } Estudiante estudiante virtual publico {get; juntos; }}
Asimismo, tambien debera agregar la class del curso a la que hacen referencia estas propiedades. La class Course tiene propiedades de navegacion a la class Inion, que contiene todas las inions actuales y anteriores.
curso de class publica {public int CourseID {get; juntos; } titulo de cadena publica {get; juntos; } [Índice] public int Credits {get; juntos; } public virtual ICollection CurrEnrollments {get; juntos; } public virtual ICollection PrevEnrollments {get; juntos; }}
El codigo primero crea la columna de clave externa {Nombre de class} _ {Clave principal}, si la propiedad de clave externa no esta incluida en una class en particular como se muestra en las classs anteriores. Cuando se genera la base de data, vera las siguientes claves externas.
Como puede ver, Code first no puede coincidir propiedades de las dos classs por si mismas. La tabla de la base de data para inions debe tener una clave externa para CurrCourse y otra para PrevCourse, pero Code First creara cuatro propiedades de clave externa, es decir,
- CurrCourse _CourseID
- PrevCourse _CourseID
- Course_CourseID y
- Course_CourseID1
Para resolver estos problemas, puede utilizar la anotacion InverseProperty para especificar la alineacion de las propiedades.
curso de class publica {public int CourseID {get; juntos; } titulo de cadena publica {get; juntos; } [Índice] public int Credits {get; juntos; } [InverseProperty ( "CurrCourse ")] ICollection publico virtual CurrEnrollments {get; juntos; } [InverseProperty ( "PrevCourse ")]public virtual ICollection PrevEnrollments {get; juntos; }}
Como puede ver, el atributo InverseProperty se aplica en la class del curso anterior especificando a que propiedad de referencia de la class de inscripcion pertenece. Ahora Code First generara una base de data y solo creara dos columnas de clave externa en la tabla Inscripciones como se muestra en la siguiente imagen.
Le recomendamos que ejecute el ejemplo anterior paso a paso para una mejor comprension.