sql server - vista - Hacer que un Modelo de Marco de Entidad abarque mĂșltiples bases de datos
que significa compatibilidad de base de datos (3)
Descubrí que este truco con sinónimos funciona perfectamente con el enfoque "Código primero" sin ninguna manipulación con los archivos de edmx.
Lo único que debe hacer es "enlazar" su clase al sinónimo apropiado en el método OnModelCreating de su DataContext.
Por ejemplo, si tengo un sinónimo para tabla Personal en otro DB (y el nombre de clase también es Personal), y el nombre del sinónimo es "myschema.MySynonym", entonces el método OnModelCreating debería ser similar a:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("myschema");
modelBuilder.Entity<Personnel>()
.ToTable("MySynonym");
Database.SetInitializer<TestSynonymContext>(null);
base.OnModelCreating(modelBuilder);
}
¿Es válido hacer algo como
CREATE SYNONYM [dbo].[MyTable] FOR [AnotherDatabase].dbo.[MyTable]
y luego modificar el archivo edmx de Entity Framework para leer este objeto como lo haría con cualquier otra tabla?
Hice una prueba de muestra rápida y parece funcionar bien para seleccionar y actualizar, pero quería saber si había alguna razón por la que no debería estar haciendo esto.
Obtengo la definición de la tabla creando un archivo edmx que apunta a la segunda base de datos, construyendo las entidades allí, luego copio / pegando la definición en el archivo edmx de la primera base de datos.
ACTUALIZAR
Si alguien está interesado, escribí lo que hice para hacer que un archivo edmx abarque varias bases de datos here . Incluye scripts para generar sinónimos y fusionar archivos de edmx.
Si hiciste una prueba y funcionó, probablemente demostraste algo que nadie más conoce. Hasta ahora siempre respondía a este tipo de preguntas: no es posible usar un solo modelo con dos bases de datos (con una solución más fea basada en vistas que ocultan tablas de la segunda base de datos). Ahora sé dos soluciones.
La única desventaja de este enfoque es que todos los cambios realizados manualmente en la parte SSDL de su EDMX siempre se perderán si ejecuta el modelo de actualización desde la base de datos . Esto significa el desarrollo manual de EDMX (que es un trabajo bastante difícil) o el uso de alguna herramienta / script que agregará los cambios después de cada actualización de la base de datos.
También puede hacer esto con vistas (y un servidor vinculado si el otro db está en un servidor diferente). Esto evitará tener que administrar / fusionar dos archivos de edmx separados. Lo he usado con un servidor vinculado para leer datos de un segundo db en un servidor diferente, pero realicé algunas pruebas rápidas para ver si las actualizaciones / inserciones / eliminaciones eran posibles y lo son.
No tengo experiencia con las transacciones distribuidas, por lo que la información relacionada con las transacciones distribuidas puede ser buena, mala o un poco de ambas. Si los dos db están en el mismo servidor, ASUMO que las transacciones distribuidas ya no se aplican.
Hay un par de cosas a tener en cuenta cuando se usa un servidor vinculado.
- Cuando modifica las entidades en las tablas db vinculadas y llama a
SaveChanges
en su contexto, esto intentará iniciar una transacción distribuida, de modo que a menos que alguien sepa cómo detener eso, debe asegurarse de que los dos servidores estén configurados para manejar las transacciones distribuidas. (Asumo que esto también sería cierto usando sinónimos). - Las inserciones en entidades con columnas de identidad en el servidor vinculado lanzan una excepción porque ef intenta obtener la nueva identificación usando
SCOPE_IDENTITY()
y es nula. No sé si hay una forma de evitar esto. No tuve problemas para actualizar o eliminar entidades en el servidor vinculado con columnas de identidad.
En SQL Server A
- crear un servidor vinculado a ServerB (omita esto si los db están en el mismo servidor).
- crear una vista en
[ServerA].[MyDB]
para cada tabla en[ServerB].[AnotherDB]
que desea acceder
En EDMX
- Agregue sus vistas al archivo edmx
- Borre la configuración de la clave de entidad de cada propiedad en el diseñador (incluido el pk real)
- Restablece la clave de entidad para el pk real
- Añadir asociaciones según sea necesario
- Guardar cambios
Para actualizaciones / insertos / elimina
- Haga clic derecho sobre su archivo edmx y ábralo con el editor xml
- Navegue a
StorageModel
->Schema
->EntityContainer
- Encuentre el conjunto de entidades para su entidad y elimine el elemento
DefiningQuery
- Encuentre la
store:Schema
atributo destore:Schema
en el conjunto de entidades y elimine elstore:
para que solo sea unSchema
. Deje su valor solo. - Repita los pasos 3 y 4 para cada vista desde el servidor vinculado
- Guardar cambios
Como usar un servidor vinculado crea una transacción distribuida, tuve que hacer un par de cosas en el ObjectContext
antes de que SaveChanges
fuera exitoso.
ctx.Connection.Open();
ctx.ExecuteStoreCommand("set xact_abort on");
ctx.SaveChanges();
ctx.Connection.Close();
Probablemente pueda crear un ObjectContext
personalizado y anular SaveChanges
para agregar esto.