Entity Problem!

7 views
Skip to first unread message

Jose Enrique Mariño Iglesias

unread,
Oct 3, 2017, 6:30:44 PM10/3/17
to improve-...@googlegroups.com

Hola grupo, un saludo a todos.

Comienzo diciendo que posiblemente sean tonterías que no he podido solucionar, pero por tal motivo siguen siendo una piedra en mi camino. Así que perdonen mi ignorancia. 
La historia corta es que estoy en una empresa que decidió migrar toda la %%&$··%&& que tienen a nuevas versiones de .net incluido la capa de acceso a datos con Entity. En principio usamos EF 5, pero he sugerido migrar a 6 directamente por temas de compatibilidad con cosas que a futuro necesitaremos. Y si no pos me da igual, por estar en el chisme de lo último + -.

Lo que hay:
                  Visual Studio 2015(c#) + EF6 + Oracle 12C ó Sql ó MySql (por el momento solo se dará el caso entre Oracle y Sql, siendo Oracle del que se va a partir)

Yo nunca he trabajado antes con Entity con responsabilidad de hacer trabajos de arquitectura ni mucho menos y ahora me han pedido que me encargue de esto y mi primer choque es que si es multi DB, por que si cambias una cadena de conexión por otra, no todo funciona?, en principio si con Sql pero no con Oracle (Y ojo, esto es cierto pues he probado y no me funciona, otra cosa es que mi manera de importar el modelo no este siendo la correcta o que se yo. Seguro que los errore son míos, pero por el momento el culpable es Entity hasta que no se pruebe lo contrario) 
Ahhh, claro, Database First, porque esto es un arrastre de un sistema super viejo. Entonces nada, tengo que lograr que sin afectar a los viejos de la empresa que están en total desacuerdo con el cambio se monten en este tren.

Después de la muela:

Cree un modelo desde cero, cuando cambie de base de datos en Oracle 12C me construye las consultas con el Schema anterior porque esta generado así el fichero .esmx y lo puedo editar como xml y quitárselo o cambiarlo, pero no es lo que necesito. También hay quien tiene métodos implementados que lo cambian automáticamente, pero no quisiera tocar lo que es generado por EF a menos que no me quede de otra.
 
Sobrecargo el constructor del contexto pero nada, no soluciono con solo cambiar la cadena de conexión en runtime.

Vi que hay una manera de decirle que el modelo tiene como Schema por defecto "X" que creo que es a partir de la versión 6 de EF pero esto no me funciona, básicamente por ser database first o eso creo yo.
Esto es sin contar que si cambias a un modelo de otro motor de DB (sql) pos peor por todo lo que genera esto. 

Por motivox XYZ, la estructura de las bases de datos "debe" ser la misma, pero los nombres de las tablas están en minúsculas en una DB y en mayúsculas en otra aun cuando se llamen iguales todos sus tablas y campos de las mismas, con lo que al importarlas en los proyectos diferentes ya generan nombres con mayúsculas o minúsculas y esto en la capa que usa este proyecto ya no funcionará. Igual, soluciones como Notations etc son paliativos, buenos para un par de tablas pero para unas miles que tiene este mostrico heredado es muy complejo. hay algunas sugerencias de hacer en runtime una conversión de los nombres, pero lo dicho, no lo veo, no me ha llevado a buen camino.

No he probado alguna lib de 3ero que sugieren algunos, con lo cual no puedo hablar de este tema.

Hice algún ejemplo con IOC y DI pero esto me ha parecido inventar una rueda partiendo de otra. Además de que no solucionaba todo y añadía más complejidad que no me han permitido abordar en esta etapa. Ahhh porque aunque "decida" un poco con arquitectura o posibles decisiones sigo siendo un peón y un mandao. Nada de jefe, ni en casa.


Soluciones temporales hasta que algún volao o "EL Volaito!!" me sugieran algo:
  - Se hizo un proyecto con cada base de datos (motores diferentes y schemas diferentes, misma estructura ya que son para el mismo software, menos la de sql que tiene el tema de las mayúsculas y minúsculas). Esta DB(su project) será enchufada en un cliente que lo necesite y se publicara solo para el, con lo cual ya nada es en runtime. No es que no funcione pero eso de cambiar mágicamente no va.
- Si se cambia de DB en tiempo de debug para probar en otro server de test etc, terminamos editando el xml y su Schema para que funcione con el otro Schema, y si se toca la DB o lo que sea se regenera todo eso y perdemos lo que no saquemos en clases partial aparte.

 Por el momento esto soluciona algo, pero cuando tenga la empresa que lidiar con los diferentes clientes que tiene y tendrá nos vamos a hacer un lío de poner y quitar proyectos, porque tenerlo todos en un proyecto tampoco se quiere, son muchas tablas y muy grandes. También hay que llamarlas del mismo modo para que lo que esta encima no se complique con nombres diferentes. etc.

Esto amigos, esto es lo que pasa cuando le dan la batuta a uno que no tiene puta idea. Aunque me estoy pensando vender pizza caliente.....

Un abrazo y a la espera de consejos.... del profesor espinosa o de los volaos.





Israel

unread,
Oct 3, 2017, 7:25:30 PM10/3/17
to improve-...@googlegroups.com
No estoy seguro si entendi cual era el problema? Que tienes el mismo esquema con diferentes providers y quieres usar el mismo DbContext y .edmx?

--

---
Has recibido este mensaje porque estás suscrito al grupo "Improve your code" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a improve-your-code+unsubscribe@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Jose Enrique Mariño Iglesias

unread,
Oct 4, 2017, 12:25:56 AM10/4/17
to improve-...@googlegroups.com
Hola Israel
Sí, es uno de los problemas.
1- Mismo provider, mismo DbContext, misma estructura de base de datos, pero en lugares físicos distintos y que se llaman diferentes, por lo que el xml que se construye en tiempo de desarrollo se crea con el nombre del Schema de la base que tenemos en el servidor de desarrollo, que aunque es la misma que en producción, allá esta con otro nombre.
Si haces un (from pp in TblPp where(x)select(Y)).ToList();   .... Esto genera un select Y from dbo.TblPp..... (dbo = Schema Name) y si las bases de datos se llamaran igual entre clientes ser'ia genial, pero no puedo cambiar eso.

2- Mismo DbContext, diferentes providers, en principio Oracle y Sql. De aquí hay dos temas, uno es que los metadata generados son en función del provider usado y el segundo problemas es que las bases de datos aunque mantienen la estructura de tablas y sus campos, están, o el Entity los importa con mayúsculas y esto cuando cambias de base de datos te cambia todo. Si te defieres al db.Tbl.Id ..... con el otro provider o contexto sería algo así como db.Tbl.ID

Es una mezcla de cosas. Pero con que funcione entre el mismo provider sin tener que tocar el xml del .dmx sería genial. 

Salu2

Israel

unread,
Oct 4, 2017, 12:50:17 AM10/4/17
to improve-...@googlegroups.com
Parece ser que una solución es generar el dbContext y el (.edmx) dinámicamente, te dejo estos links:



Tienen por lo menos 2 anos estos artículos, es posible tengas que cambiar algo, pero la idea sigue siendo la misma.

Saludos
Israel.

Carlos A. Osoria

unread,
Oct 11, 2017, 11:41:30 AM10/11/17
to improve-...@googlegroups.com
Hola Pepe 

Como esta la cosa, no se por donde andes con la solucion de este problema, pero a mi me suena como que tienes que agregar una capa entre el codigo que quiere datos y la tu capa de datos (another layer of indirection) esta capa seria la encarga de traducir algunas llamadas en caso que sea necesario.

Aca algunos conceptos que use en el pasado para lograr usar EF 6.0 mas dinamicamente 

Conceptos 

- En el DbContext usar DbSet<T> en vez de por ejemplo Customers (Open vs Closed Generic) esto me permite no que generar hardcoded DbSet en el DbContext y hacer queries para diferentes entidades on al vuelo. 

- Usar "CodeFirst Mapping Clases" para tus entidades y cargar estas clases de mappeo al vuelo. En el projecto yo lo que hice fue que cree una clase que derivaba de EntityTypeConfiguration<TConfiguration> y la applicacion dinamicamente cargaba todas las clases que podia encontrar en el assembly de este modo el DbContext quedaba configurado al vuelo.

- Usar POCOs como entidades y EF Code First, claro como tu tienes databases existentes que fue nuestro caso tambien,  entonces te recomiendo una herramienta llamada "EF Power Tools"(haga click para navegar) que permite generar las clases de mapeos y entidades en modo Code First para una database ya existente.

En un final la estrategia que propongo quedaria mas o menos asi:
- Crear una interface comun para acceso a datos por ejemplo usando IRepository<T> y IReadOnlyRespository<T>
- Crear una capa donde se pueden agregar codigo de traducion entre el cliente y la capa de datos en caso necesario. (cliente en este caso significa el componente que quiere datos, no la capa de presentacion)
- Crear las clases de mapping y las entidades POCO para las dos bases de datos usando EF Power Tools 
- Tener dos DbContext separados que son selecionados por la capa de traducion inteligente dependiendo de cada caso
- Usar DbSet<T> 
- Configurar el DbContext dinamicamente usando una clase derivada de EntityTypeConfiguration<TConfigurationEntity> y una convencion de namespaces para que todo sea mas dinamico. 
- Al arrancar la aplicacion o cuando se necesite buscar dinamicamente las configurationes para cada uno de los dbcontext y configurarlos dinamicamente.

Aca te pongo algunas de las clases que pude encontrar para que los uses como inspiracion ... en este caso usamos el Unit of Work y Repository Pattern para manejar el acceso a datos.


DynamicEntityTypeConfiguration<TConfiguration>
Clase base para las configuraciones 

EntityFrameworkContext<TContext>
Clase que carga las configuraciones dinamicamente buscando en el assembly

EntityFrameworkRepository<TEntity>
Repository Pattern con entity framework


ApplicationDbContext<TContext>
Clase base para los DbContext de la applicacion



Saludos
Carlis


Eng. Carlos A. Osoria.
carlos...@gmail.com

Carlos A. Osoria

unread,
Oct 11, 2017, 11:51:33 AM10/11/17
to improve-...@googlegroups.com
Oh otra cosita mas... 

Mucho de los conceptos de como usar EF dinamicamente me los lei en el codigo de un projecto llamado Orchard CMS de microsoft. 

Aca te dejo el link. ( No mires la version de ASP.NET Core pues EF Core aun esta en pannales con respecto a EF )


Claro de eso hace ya como 3 annos me imagino que esta gente ya estaran mucho mas avanzados, lee el codigo de como Orchard carga los plugins dinamicamente y como estos plugins accesan la base datos dinamicamente sin tener que tener todo hardcoded. 

Saludos
Carlos



Reply all
Reply to author
Forward
0 new messages