Compartir a través de


Datos

En esta sección se describe cómo WCF RIA Services trata los escenarios que afectan al modelado de datos, la comprobación de la validez de los datos y el aseguramiento de la simultaneidad de datos. Cuando se proporciona una interfaz para actualizar, eliminar o crear datos en el cliente de una aplicación de Internet enriquecida (RIA), suele ser necesario modelar algunas relaciones de datos complicadas y asegurarse de que los datos del usuario son válidos y siguen siendo vigentes respecto a los datos del origen de datos antes de confirmar los cambios de los datos

Normalmente, debe utilizar Entity Data Model o LINQ to SQL para modelar los datos que existen en una base de datos relacional. Sin embargo, no se requiere que utilice una base de datos en un proyecto de RIA Services . Puede utilizar cualquier tipo de objeto para almacenar los datos. El código en el proyecto de cliente que facilita las operaciones de datos es indiferente al origen de datos en el sentido de que, realmente, desconoce la tecnología de acceso a datos o el esquema utilizado por el nivel intermedio.

Relaciones de datos

RIA Services proporciona características que permiten interactuar con relaciones de datos complicadas, como modelos jerárquicos, modelos de herencia polimórficos, modelos de presentación que consolidan valores de muchas entidades y modelos que incluyen valores de más de un servicio de dominio. El modelo jerárquico representa una relación compuesta primaria y secundaria, como Order y OrderDetails, o una relación recursiva, como un modelo Employee que incluye un campo para un ManagerID que señala otra entidad en el modelo Employee. Para obtener más información, vea Jerarquías composicionales.

En un modelo de herencia, puede representar una estructura de datos que incluya una entidad Customer y dos entidades que deriven de ella: PublicSectorCustomer y PrivateSectorCustomer. Mediante el uso de operaciones de dominio, puede consultar y actualizar los tipos. Para obtener más información, vea Herencia en modelos de datos.

Se ha agregado compatibilidad con tipos complejos que no son de entidad en RIA Services v. 1.0 SP1. Concretamente, se proporciona compatibilidad con CODEGEN, metadatos, validación profunda, seguimiento de cambios, sesiones de edición y parámetros de tipo complejo. Esto significa que los tipos personalizados, como Address, se pueden utilizar ahora como propiedades de entidad, parámetros o valores devueltos en métodos DomainService. Para obtener más información, vea el tema Tipos complejos.

Se ha agregado compatibilidad con el uso compartido de una entidad con varios servicios de dominio en RIA Services v. 1.0 SP1. De este modo se habilita la flexibilidad necesaria para segmentar las clases DomainService de forma más lógica. Para obtener más información, vea el tema Entidades compartidas.

En un modelo de presentación, puede generar tipos para el nivel de presentación que no estén ligados directamente a la estructura de las tablas de origen de datos. Por ejemplo, puede generar un tipo de datos denominado CustomerPresentation que esté basado en clases de datos para las tablas Customer, CustomerAddress y Address. En el tipo de presentación, solo se agregan los valores que son relevantes para el nivel de presentación. Si se realizan cambios en el repositorio de datos, puede cambiar solamente el tipo de presentación y no actualizar la aplicación cliente de código que interactúa con los datos. RIA Services permite actualizar los datos a través del tipo de presentación. Para obtener más información, vea Modelos de presentación.

Finalmente, en la aplicación, puede que sea necesario mostrar datos de una variedad de orígenes de datos o exponer una entidad única a más de un servicio de dominio. RIA Services habilita este escenario admitiendo referencias entre entidades de tipos DomainContext diferentes. Por ejemplo, es posible que un sitio web de comercio electrónico necesite integrar datos de su sistema de procesamiento de pedidos con productos de un servicio de dominio de otro fabricante. Para obtener más información, vea Tutorial: compartir entidades entre varios servicios de dominio.

Anotaciones y validación de datos

Cuando utilice clases de datos en su aplicación de RIA Services , puede aplicar atributos a la clase o los miembros que especifican reglas de validación, especificar cómo se han de mostrar los datos y establecer relaciones entre clases de entidad. El espacio de nombres System.ComponentModel.DataAnnotations contiene las clases que se utilizan como atributos de datos. Mediante la aplicación de estos atributos en la clase o el miembro de datos, puede centralizar la definición de datos y no tener que volver a aplicar las mismas reglas en varias ubicaciones. Los atributos de anotación de datos se organizan en tres categorías: atributos de validación, atributos de visualización y atributos de modelado de datos. Para obtener más información, vea Uso de anotaciones de datos para personalizar clases de datos y Validar datos. Para la validación, puede utilizar los atributos siguientes:

  1. DataTypeAttribute

  2. RangeAttribute

  3. RegularExpressionAttribute

  4. RequiredAttribute

  5. StringLengthAttribute

  6. CustomValidationAttribute

Cuando se trabaja con clases de datos que se generan automáticamente, como clases de Entity Data Model o LINQ to SQL, no se deben aplicar los atributos directamente a las clases generadas porque los atributos se perderán la próxima vez que se vuelva a generar la clase. En su lugar, se debe crear una clase de metadatos para la clase de datos y aplicar los atributos a la clase de metadatos. Una clase de metadatos es una clase parcial que se designa desde la clase de datos como el tipo de metadatos. Para obtener más información, vea Agregar clases de metadatos.

En el ejemplo siguiente se muestra una clase de metadatos con los atributos RoundtripOriginalAttribute, RequiredAttribute, StringLengthAttribute y ExcludeAttribute aplicados a algunas propiedades.

<MetadataTypeAttribute(GetType(Address.AddressMetadata))>  _
Partial Public Class Address
    
    Friend NotInheritable Class AddressMetadata
        
        'Metadata classes are not meant to be instantiated.
        Private Sub New()
            MyBase.New
        End Sub
        
        Public AddressID As Integer

        <Required()> _
        <StringLength(60)> _
        <RoundtripOriginal()> _
        Public AddressLine1 As String

        <RoundtripOriginal()> _
        Public AddressLine2 As String

        <Required()> _
        <StringLength(30)> _
        <RoundtripOriginal()> _
        Public City As String

        <RoundtripOriginal()> _
        Public CountryRegion As String
        
        Public CustomerAddresses As EntityCollection(Of CustomerAddress)

        <RoundtripOriginal()> _
        Public ModifiedDate As DateTime

        <Required()> _
        <RoundtripOriginal()> _
        Public PostalCode As String

        <Exclude()> _
        Public rowguid As Guid

        <RoundtripOriginal()> _
        Public StateProvince As String
    End Class
End Class
[MetadataTypeAttribute(typeof(Address.AddressMetadata))]
public partial class Address
{

    internal sealed class AddressMetadata
    {
        // Metadata classes are not meant to be instantiated.
        private AddressMetadata()
        {
        }

        public int AddressID { get; set; }

        [Required]
        [StringLength(60)]
        [RoundtripOriginal]
        public string AddressLine1 { get; set; }

        [RoundtripOriginal]
        public string AddressLine2 { get; set; }

        [Required]
        [StringLength(30)]
        [RoundtripOriginal]
        public string City { get; set; }

        [RoundtripOriginal]
        public string CountryRegion { get; set; }

        public EntityCollection<CustomerAddress> CustomerAddresses { get; set; }

        [RoundtripOriginal]
        public DateTime ModifiedDate { get; set; }

        [Required]
        [RoundtripOriginal]
        public string PostalCode { get; set; }

        [Exclude]
        public Guid rowguid { get; set; }

        [RoundtripOriginal]
        public string StateProvince { get; set; }
    }
}

Puede crear un atributo de validación personalizado agregando un archivo de código compartido y creando en ese archivo una clase que implemente la lógica de validación. Cuando defina la clase de validación personalizada, debe proporcionar al menos algún fragmento de código distinto de las propiedades implementadas automáticamente para que la clase se genere correctamente en el proyecto de cliente. Para obtener un ejemplo, vea Validar datos.

La clase Entity implementa la interfaz INotifyDataErrorInfo. Esta interfaz define miembros que proporcionan compatibilidad de validación sincrónica y asincrónica. Con la interfaz INotifyDataErrorInfo, los errores de validación se comunican al proyecto de cliente sin producir una excepción. Para obtener más información sobre INotifyDataErrorInfo, vea INotifyDataErrorInfo (Interfaz).

El resultado de una comprobación de validación se devuelve creando una instancia de la clase ValidationResult.

En el ejemplo siguiente se muestra una clase de validación personalizada que devuelve los resultados a través de una instancia de la clase ValidationResult.

Imports System
Imports System.ComponentModel.DataAnnotations

Public Module GenderValidator
    Public Function IsGenderValid(ByVal gender As String, ByVal context As ValidationContext) As ValidationResult
        If gender = "M" OrElse gender = "m" OrElse gender = "F" OrElse gender = "f" Then
            Return ValidationResult.Success
        Else
            Return New ValidationResult("The Gender field only has two valid values 'M'/'F'", New String() {"Gender"})
        End If
    End Function
End Module
using System;
using System.ComponentModel.DataAnnotations;

namespace HRApp.Web
{
    public static class GenderValidator
    {
        public static ValidationResult IsGenderValid(string gender, ValidationContext context)
        {
            if (gender == "M" || gender == "m" || gender == "F" || gender == "f")
            {
                return ValidationResult.Success;
            }
            else
            {
                return new ValidationResult("The Gender field only has two valid values 'M'/'F'", new string[] { "Gender" });
            }
        }
    }
}

Simultaneidad de datos

WCF RIA Services admite la simultaneidad optimista para garantizar la coherencia de los datos y se basa en la capacidad de los desarrolladores para proporcionar la lógica necesaria para controlar los conflictos que puedan producirse al actualizar un origen de datos. Si permite que los usuarios actualicen o eliminen datos, debe asegurarse de que otro proceso no haya cambiado los datos del origen de datos.

De forma predeterminada, RIA Services no pasa la entidad original completa, junto con los valores modificados, a la capa de acceso a datos para comprobar la simultaneidad de los datos. En su lugar, RIA Services almacena y devuelve solamente los miembros marcados con el atributo RoundtripOriginalAttribute. Con esta implementación, puede optimizar el rendimiento de su aplicación mediante la especificación únicamente de aquellos miembros que quiere que participen en la comprobación de simultaneidad.

El comportamiento se implementa aplicando el atributo a propiedades de una clase de metadatos o a la propia o propias clases de metadatos cuando se trabaja con Entity Framework. También se puede aplicar directamente a propiedades o clases de tipos CLR cuando se trabaja con modelos de datos definidos con POCO. Para obtener más información, vea Agregar clases de metadatos.

Transacciones

El marco de RIA Services no crea las transacciones automáticamente, pero puede agregar transacciones explícitas al enviar los cambios. Para crear una transacción explícita propia, debe reemplazar el método Submit. Para obtener más información, vea Agregar transacciones explícitas a un servicio de dominio.

Vea también

Conceptos

Seguridad para WCF RIA Services