Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los servicios de datos de ADO.NET admiten de forma nativa los modelos ADO.NET Entity Framework y proporcionan una extensión mediante la cuál un modelo de datos se puede definir utilizando objetos de Common Language Runtime (CLR). La terminología de Entity Data Model (EDM), específicamente el lenguaje de definición de esquemas conceptuales (CSDL) y términos como EntitySet, EntityType, Property, Association, AssociationSet, etc. se usan para describir los datos implementados por el marco de trabajo de los servicios de datos de ADO.NET. Para obtener las definiciones de estos términos, vea Terminología del marco de trabajo de los servicios de datos de ADO.NET. Para obtener más información acerca de CSDL, vea Especificaciones del EDM.
Con la reducción de los orígenes de datos a una gramática única y a convenciones de URI uniformes, los servicios de datos de ADO.NET implementan representaciones de datos coherentes independientemente del origen de datos subyacente. Cuando se usa un modelo de Entity Framework, la configuración de un servicio de datos es trivial. Para los modelos basados en CLR, se ha definido una asignación entre objetos de CLR y tipos de EDM.
Modelo de datos EDM
En el modelo Entity Data Model (EDM), los servicios de datos de ADO.NET interactúan con el nivel de Servicios de objeto de Entity Framework, que es un contexto programable en CLR. Aunque el contexto de programación y el modelo conceptual se pueden crear manualmente, el método recomendado es usar las Herramientas de Entity Data Model integradas con Microsoft Visual Studio 2008 a partir del Service Pack 1.
Para obtener un ejemplo en el que se usa EDM y las herramientas de Entity Framework, vea Inicio rápido del servicio de datos (marco de trabajo de los servicios de datos de ADO.NET).
Modelo de datos basado en CLR
Los servicios de datos de ADO.NET funcionan convirtiendo las solicitudes de URI en operaciones sobre los datos direccionados mediante la sintaxis de URI. Cuando el modelo de datos se basa en Entity Framework, los URI se convierten en llamadas a método de Servicios de objeto. ObjectContext de Entity Framework implementa conjuntos de datos basándose en ObjectQuery<T> y ObjectQuery<T> implementa IQueryable<T>.
Cualquier tecnología o proveedor de datos que despliega los datos implementando un derivado de IQueryable se puede implementar como un servicio de datos de ADO.NET. El método de extensión AsQueryable, disponible a partir de .NET Framework 3.5, se puede usar con objetos que implementan IEnumerable<T>. Todas las clases de .NET Framework que implementan IEnumerable<T> se pueden ampliar llamando al método de extensión AsQueryable. Esto significa que la mayoría de las listas, matrices y colecciones se pueden implementar de forma eficaz como servicios de datos de ADO.NET.
Las consultas de LINQ también funcionan con orígenes de datos que implementan IEnumerable<T> o IQueryable<T>. Cuando el modelo de datos subyacente de un servicio de datos de ADO.NET se define utilizando objetos de CLR, los URI de solicitud se convierten en consultas de LINQ. Se define una asignación completa entre los objetos de CLR y los recursos de servicios de datos de ADO.NET. La asignación de objetos de CLR a conjuntos de entidades de ADO.NET permite que los servicios de datos de ADO.NET implementen los orígenes de datos que se pueden leer en memoria como una matriz, una lista o una colección.
Ejemplo 1: Clases de CLR para recursos del servicio de datos de ADO.NET
En el ejemplo siguiente se muestra la asignación entre los constructores de CLR y los recursos de los servicios de datos de ADO.NET. Las clases que implementan la interfaz IQueryable<T> se representan como conjuntos de entidades.
En el ejemplo siguiente se usa el método de extensión AsQueryable para convertir una matriz de Customers al formato IQueryable<T>. La matriz de Customers se crea aquí de forma sencilla, pero los datos de la aplicación se podrían leer desde casi cualquier origen.
El ejemplo de código tiene anotaciones para indicar cómo se asignan los tipos de CLR a los tipos de recursos de los servicios de datos de ADO.NET.
namespace Accounting // Namespace
{
public class DataModel // EntityContainer
{
public IQueryable<Customer> Customers // EntitySet
{
get
{
return new Customer[] { new Customer(1, "name1"),
new Customer(2,
"name2") }.AsQueryable<Customer>();
}
}
}
public class Customer // EntityType
{
private int _ID;
private string _name;
private Address _address;
public Customer(int i, string name)
{
_ID = i;
_name = name;
_address.Line1 = "Line" + i;
_address.Line2 = "Line" + i;
}
[DataWebKeyAttribute]
public int ID // Entity Type Key
{
get { return _ID; }
}
public string CustName // Property
{
get { return _name; }
}
public Address Address // Property
{
get { return _address; }
}
}
public struct Address // ComplexType
{
private string line1;
private string line2;
public string Line1 // Property
{
get { return this.line1; }
set { this.line1 = value; }
}
public string Line2 // Property
{
get { return this.line2; }
set { this.line2 = value; }
}
}
}
Al asignar una entidad de CLR a un recurso de servicios de datos de ADO.NET, el recurso de servicios de datos de ADO.NET asociado copia el uso de mayúsculas y minúsculas del nombre de CLR. Los tipos de CLR que corresponden a los recursos de servicios de datos de ADO.NET, como se indica mediante los comentarios del código anterior, se describen en la lista siguiente.
Contenedores de entidades y conjuntos de entidades
Se usa una clase de CLR pública única (C1) dentro de un espacio de nombres definido explícitamente para definir todos los conjuntos de entidades de nivel superior del modelo. Los recursos de nivel superior son accesibles mediante el primer segmento de ruta de acceso de un identificador URI.
El espacio de nombres en el que la clase C1 existe es el que identifica C1 como el contenedor de entidades. Este es constante aun cuando C1 sea un tipo derivado.
El nombre de la clase C1 representa el contenedor de entidades. Se puede definir un contenedor de entidades único para el espacio de nombres. Este es constante aun cuando C1 sea un tipo derivado.
Cada conjunto de entidades se debe representar como una propiedad pública (P1) de la clase C1 con un tipo devuelto de IQueryable<T>. Pueden existir cero o más propiedades de este estilo en la clase C1 o, si la clase es un tipo derivado, en una de sus clases primarias.
T representa el tipo de entidad dentro del conjunto de entidades.
T debe tener una propiedad adecuada para ser una clave de entidad a fin de que la propiedad C1 se considere como un conjunto de entidades. Si no existe una propiedad adecuada de clave de este estilo, la propiedad P1 se omite y el servicio de datos de los Servicios de datos de ADO.NET no considera que C1 represente un conjunto de entidades.
Más de una propiedad de la clase C1 o de una clase primaria de C1 no pueden devolver el mismo tipo T. Esta definición de modelo basado en CLR no admite incluir el mismo tipo de entidad, en este caso representado por la clase T, en varios conjuntos de entidades. Se pueden implementar varios conjuntos de entidades por tipo en Entity Framework pero no como clases implementadas por los servicios de datos de ADO.NET.
Tipos de entidad, propiedades y vínculos de navegación
Una clase pública de CLR (C1) representa un tipo de entidad.
Para que se reconozca como un tipo de entidad, una clase debe tener una propiedad o propiedades que representan la clave del tipo. Esa propiedad o ese grupo de propiedades pasan a ser la clave o claves del tipo de entidad. Las reglas para las propiedades que representan una clave son:
Propiedad pública denominada ID.
Propiedad pública denominada <nombreDeClase>ID.
Propiedades públicas marcadas con el atributo DataWebKeyAttribute.
Si una clase contiene una propiedad o un grupo de propiedades que están marcadas con el atributo DataWebKeyAttribute, esas propiedades se utilizan como la clave y se omiten las dos primeras reglas. Si ninguna propiedad contiene el atributo esas propiedades que coinciden con las dos primeras reglas determinan la propiedad de clave del tipo de entidad. Si más de una propiedad coincide con las reglas, el tipo de entidad tiene, por definición, una clave compuesta.
Si la clase C1 es parte de una jerarquía, la jerarquía de clases se traduce en una jerarquía de tipos de entidad aplicando las reglas siguientes:
- La clase de CLR más próxima a la raíz de la jerarquía de clases que incluye una propiedad de clave válida pasa a ser la raíz de la jerarquía de tipos de entidad. Si la clase C1 no es la raíz de la jerarquía de clases de CLR en la que participa, se asume que las propiedades declaradas por las clases anteriores a C1 en la jerarquía las ha declarado C1.
Cada propiedad (P) declarada por la clase C1 se traduce en una propiedad en el tipo de entidad si la propiedad de CLR cumple todas las convenciones siguientes:
La propiedad de CLR debe tener un ámbito público.
La propiedad de CLR debe implementar un método get para la propiedad.
La propiedad de CLR no debe ser un indizador.
Si el tipo devuelto de la propiedad P es un tipo primitivo, y el tipo corresponde a un tipo de EDM, la propiedad debe representarse como una propiedad. Vea Tipos de contenido de los servicios de datos de ADO.NET para obtener una asignación de tipos de EDM a tipos de CLR.
Si el tipo devuelto de la propiedad P es un tipo de referencia, y el tipo o uno de sus objetos primarios, si es un tipo derivado, representa un tipo de entidad, P representa un vínculo de navegación (1-1).
Si el tipo devuelto de la propiedad P es IEnumerable<T> y T representa un tipo de entidad, P representa un vínculo de navegación uno con muchos.
Si el tipo devuelto de la propiedad P es un tipo de valor, P representa un tipo complejo.
Tipos complejos
Un tipo de valor de CLR público (V1) representa un tipo complejo.
Cada propiedad del tipo de valor V1 se traduce en una propiedad de un tipo complejo. Los tipos complejos siguen reglas similares a los tipos de entidad para determinar si se asignará una propiedad de CLR a una propiedad.
La propiedad de CLR debe tener un ámbito público.
La propiedad de CLR debe implementar un método Get para la propiedad.
La propiedad de CLR no debe ser un indizador.
Si el tipo devuelto de la propiedad P es un tipo de referencia, y el tipo o uno de sus objetos primarios, si es un tipo derivado, representa un tipo de entidad, P representa un vínculo de navegación uno con uno.
Ejemplo 2: Clases de CLR para recursos del servicio de datos de ADO.NET
En el ejemplo siguiente se muestran clases de CLR que incluyen la herencia usada para implementar los tipos de recursos de los servicios de datos de ADO.NET.
namespace Accounting
{
public class DataModel
{
public IQueryable<Customer> Customers
{
get
{
return new Customer[] { new Customer(1, "name1"),
new Customer(2, "name2") }.AsQueryable<Customer>();
}
}
public IQueryable<Order> Orders
{
get
{
return new Order[] { new Order(1, "order1"),
new Order(2, "order2") }.AsQueryable<Order>();
}
}
}
public class DerivedDataModel : DataModel
{
public IQueryable<HumanResources.Employee> Employees
{
get { return new HumanResources.Employee[] { new
HumanResources.Employee(1, "EmpName1"), new
HumanResources.Employee(2, "EmpName2")
}.AsQueryable<HumanResources.Employee>();
}
}
}
public class Person
{
protected int _ID;
public Person() { }
public Person(int i)
{
_ID = i;
}
[DataWebKeyAttribute]
public int ID
{
get { return _ID; }
}
}
public class Customer : Person
{
private string _name;
private Address _address;
List<Order> _orders;
public Customer(int i, string name)
{
_ID = i;
_name = name;
_orders = new List<Order>();
if (i == 1) { _orders.Add(new Order(1, "order1")); }
if (i == 2) { _orders.Add(new Order(2, "order2")); }
_address.Line1 = "Line" + i;
_address.Line2 = "Line" + i;
}
public string CustName
{
get { return _name; }
}
public Address Address
{
get { return _address; }
}
public IList<Order> Orders
{
get { return _orders; }
}
}
public class Order
{
private int _ID;
private string _name;
public Order(int i, string name)
{
_ID = i;
_name = name;
}
[DataWebKeyAttribute]
public int OrderKey
{
get { return _ID; }
}
public string OrderName
{
get { return _name; }
}
}
public struct Address
{
private string line1;
private string line2;
public string Line1
{
get { return this.line1; }
set { this.line1 = value; }
}
public string Line2
{
get { return this.line2; }
set { this.line2 = value; }
}
}
}
namespace HumanResources
{
public class Employee
{
private int _ID;
private string _name;
public Employee(int i, string name)
{
_ID = i;
_name = name;
}
public int ID
{
get { return _ID; }
}
public string EmpName
{
get { return _name; }
}
}
}
Compatibilidad con la escritura y actualización
Para habilitar la compatibilidad con las operaciones de crear, actualizar y eliminar en un modelo de datos de CLR, la clase que crea un modelo de los conjuntos de entidades de nivel superior debe implementar la interfaz IUpdatable. En la referencia al Ejemplo 2, los objetos de CLR para el marco de trabajo de los servicios de datos de ADO.NET anterior, se requeriría la clase Accounting.DataModel para implementar la interfaz IUpdatable.
Vea también
Conceptos
Especificaciones del servicio de datos de ADO.NET