2011-02-12 8 views
10

¿Hay alguna forma de redactar consultas a partir de 2 modelos de entidades diferentes si los modelos están llegando a la misma base de datos subyacente?Redactar consultas en los modelos de datos de entidad

El escenario que tengo es la siguiente: tengo un marco que utiliza EF para acceso a datos (EDM 1) Tengo una aplicación cliente que utiliza los servicios de la estructura y también utiliza EF para su propio acceso de datos (.. EDM2)

Hay situaciones en las que necesito redactar consultas y unirme a entidades que abarcan los 2 EDM.

¿Hay alguna manera de hacer esto sin obtener los datos en la memoria del primer EDM y luego aplicar predicados/uniones adicionales en la memoria de las entidades del 2º EDM?

espero que estoy articulando esta manera el derecho

EDITAR @Ladislav Mrnka: El primer EDM es la capa de acceso a datos para un marco reutilizable. No tiene sentido acoplar las entidades EF generadas a partir de este EDM con las del cliente consumidor Se derrota la reusabilidad de la API si hiciera esto y tendría que llevar a cabo un engatillado adicional (metadatos EF y DB tablas del cliente) cada vez que quería volver a implementar el marco. También esto haría que la gestión del modelo en el diseñador sea difícil de manejar.

actualmente estoy usando lo que mencionas n artículo 7 como el solutuon y el rendimiento es abismal debido al hecho de que tengo que terminar volviendo más datos (es decir, entidades) a partir de las necesarias marco usando EDM1 y luego filtra los que no se necesitan en función de los predicados/condiciones según el valor de propiedades de entidades en el segundo EDM. El resultado final es una gran degradación del rendimiento y un DBA infeliz.

Por esta razón terminé empujando la lógica necesaria para recuperar las entidades a un procedimiento almacenado en el que puedo acceder a las tablas que utilizan ambos EDM y aplicar los predicados necesarios y tienen toda la tirada de consulta en la base de datos en contraposición para traer los datos en la memoria y luego filtrar ones.Downside innecesaria es que no puedo utilizar LINQ

artículo 8 que lo mencionas suena interesante, pero de lo que suena dudo que se obtiene una gran escritura en el diseño tiempo, ¿o sí? ¿Puedes subir tu código de muestra a algún lugar para que yo pueda probarlo?

+0

¿No puede hacer esto en la parte de atrás o los catálogos de la base de datos sql no se ven a través de un servidor vinculado o equivalente? – CarneyCode

+0

@ Carnotaurus: Eso es lo que estoy haciendo actualmente. Las tablas para ambos EDM están en el mismo DB, así que estoy usando un Sproc para consultar las tablas del framework (EDM1) y las del cliente (EDM2). La desventaja es que no puedo usar LINQ –

+0

Agregué la etiqueta EF4 porque la mayoría de las características descritas en mi respuesta son válidas solo en EF4. –

Respuesta

4

editar Importante

No hay acumulación de apoyo para lograr esto con dos tipos ObjectContext. Su consulta siempre debe ejecutarse contra el único ObjectContext.

Probablemente la mejor manera de hacerlo: Esto fue lo suficientemente interesante como para probarlo yo mismo. Empecé con una idea muy simple. Dos archivos EDMX (utilizados con generadores POCO T4), cada uno con una sola entidad. Tomo la descripción de metadatos de la segunda cadena de conexión y la agregué a la primera cadena de conexión. Usé ObjectContext y ObjectSet directamente. Al hacer esto, pude consultar y modificar ambas entidades desde la única instancia de ObjectContext. También intenté crear entidades de unión de consultas de ambos modelos y funcionó. Obviamente, esto solo funciona si ambas correlaciones de EDMX a la misma base de datos (misma cadena de conexión de db).

La parte importante es conexiones cadena:

<configuration> 
    <connectionStrings> 
    <add name="TestEntities" connectionString="metadata=res://*/FirstModel.csdl|res://*/FirstModel.ssdl|res://*/FirstModel.msl|res://*/SecondModel.csdl|res://*/SecondModel.ssdl|res://*/SecondModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.;Initial Catalog=Test;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" /> 
    </connectionStrings> 
</configuration> 

cadena Esta conexión contiene los metadatos de los dos modelos - FirstModel.edmx y SecondModel.edmx.

Otro problema es forzar EF para utilizar la asignación de estos dos archivos. Cada archivo EDMX debe definir contenedor único para SSDL y CSDL. ObjectContext ofrece una propiedad llamada DefaultContainerName. Esta propiedad se puede establecer directamente o mediante algunas sobrecargas de constructor. Una vez que establezca esta propiedad, debe vincular su instancia ObjectContext a un solo EDMX; para este escenario , no debe configurar esta propiedad. Omitir DefaultContainerName puede tener algunas consecuencias porque algunas características y declaraciones pueden dejar de funcionar (obtendrá errores de tiempo de ejecución). No debería tener problemas con POCO a menos que desee utilizar algunas funciones avanzadas. . Lo más probable que tenga proplems si está utilizando objetos Entity (entidades EF pesada Todos los métodos que utilizan conjuntos de entidades definidas como cadenas dependen de contenedores Debido a esta sugiero utilizar dicha configuración sólo cuando sea necesario -. Para modelos transversales consultas

.

último problema es la generación de entidades y "inflexible" deriva ObjectContext El camino a seguir es modificar la plantilla T4 para que una plantilla lee datos de varios archivos EDMX y genera entidades finales contexto para todos ellos -. ya haciendo esto en mi proyecto y funciona La implementación predeterminada de T4 no sigue el enfoque necesario descrito en el párrafo anterior. Derivada de ObjectContext de la implementación de T4 predeterminada, depende de un solo EDMX y contenedor de entidad.


Esta parte se ha escrito antes de la edición anterior.

estoy dejando el resto de la información sólo porque algunos de ellos pueden ser útiles en otros escenarios, incluyendo el trabajo con múltiples bases de datos.

ORM como marco entidad opera en la parte superior de mapeo entre mundo de los objetos y el mundo base de datos. En EF, el mundo de los objetos se describe en CSDL, el mundo de la base de datos se describe como SSDL y el mapeo entre ellos se describe como MSL (todos son solo XML con un esquema bien conocido). En el momento del diseño, estas descripciones son parte del modelo almacenado en el archivo EDMX. Durante la compilación, estas descripciones se extraen de EDMX y, por defecto, se incluyen como archivos de recursos para el ensamblaje compilado.

Cuando crea la instancia de ObjectContext, recibe cadenas de conexiones que contienen referencias a los archivos de recursos CSDL, SSDL y MSL. SSDL o MSL no especifican el elemento de inclusión para agregar información de otros archivos. CSDL ofrece el elemento Using que le permitirá volver a utilizar la asignación existente, pero esta característica no es compatible con el diseñador. ConnectionString se usa para inicializar la instancia EntityConnection que a su vez se utiliza para inicializar ObjectContext MetadataWorkspace (información de mapeo en tiempo de ejecución). También ObjectContext no proporciona ninguna funcionalidad de anidar múltiples contextos en hiearchy. La cadena de conexión no puede contener referencia a varias instancias de estos archivos. Editar: Puede. Acabo de probarlo. Ver los párrafos iniciales.

Cuando se ejecuta LINQ o consulta ESQL en la instancia de ObjectContext que usese MSL para mapear sus entidades o clases POCO (definidos por CSDL) en consulta DB (definida por la descripción SSDL de tablas de bases de datos).Si no tiene esta información, no funcionará (y no puede tener esa información si está almacenada en EDMX por separado).

Entonces, ¿cómo resolver este problema? Hay varias maneras:

  1. tener siempre en cuenta: combinar sus mapeo en un solo archivo (si varios archivos se utilizan para la misma base de datos). Se supone que es una forma de usar EF y, como mencionaste, estás consultando el mismo DB, por lo que no se necesitan dos modelos de EF.
  2. Descripción de entidad duplicada en el segundo modelo. Si usa EF4 y POCO, puede asignar las mismas descripciones de varios modelos en una definición de clase POCO. No me gusta esta solución, pero a veces puede ser útil.
  3. Defina la vista de base de datos o el procedimiento almacenado que contiene su consulta (o núcleo de su consulta) y asóciela en un modelo a entidad nueva.
  4. Usa DefiningQuery en un modelo (probablemente necesitarás el tercero si usas la función Actualizar desde la base de datos) y lo correlaciona con una entidad nueva. DefiningQuery es una consulta SQL personalizada definida en SSDL en lugar de tabla o descripción de vista.
  5. Use Function con CommandText personalizado que especifica la consulta DB. Es similar al uso de DefiningQuery y tiene la misma limitación. Debe mapear manualmente (en EDMX) el resultado de la función en un nuevo tipo complejo (otra diferencia a DefiningQuery que se asigna a la nueva entidad).
  6. Defina el nuevo tipo para el resultado de la consulta (las propiedades del tipo deben tener los mismos nombres que las columnas devueltas en la consulta) y use ObjectContext ExecuteStoreQuery (solo en EF4).
  7. Divida la consulta en dos partes, cada una ejecutada por separado en su propio contexto y use linq-to-objects para obtener el resultado. No me gusta esta solución.

  8. Esta es solo una idea de alto nivel: no lo probé y no sé si funciona. Como se describió anteriormente, la asignación del tiempo de ejecución depende del contenido de la instancia MetadataWorkspace que se completa desde EntityConnection. EntityConnection también proporciona el constructor que recibe la instancia MetadataWorkspace directamente. Por lo tanto, en general, si fuera posible completar MetadataWorkspace desde múltiples EDMX, no necesitará múltiples instancias de ObjectContext, pero su mapeo aún estará separado en dos EDMX. Es de esperar que esto le permita escribir consultas Linq personalizadas sobre dos archivos de mapeo). Editar: Debe ser posible porque es exactamente lo que EF está haciendo si define múltiples asignaciones en la cadena de conexión.

  9. Utilice CSDL Using feature para dividir el modelo en varias partes reutilizadas.

+0

gracias por vosotros responses.I detalladas tienen una un montón de comentarios para agregar mis comentarios a la pregunta original como EDITAR ya que tengo caracteres limitados para agregar comentarios ... –

Cuestiones relacionadas