2010-04-16 8 views
9

Mi proyecto necesita manejar tres bases de datos, eso significa tres fábricas de sesión. La cosa es que si hago algo como esto con nhibernate fluidez:Fluido NHibernate + bases de datos múltiples

.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly())) 

las fábricas recogerían todas las asignaciones, incluso los que corresponden a otra base de datos

he visto que cuando se utiliza se automapping puede hacer algo como esto, y filtrar por espacio de nombres:

.Mappings(m => m.AutoMappings.Add(
    AutoMap 
     .AssemblyOf<Product>() 
     .Where(t => t.Namespace == "Storefront.Entities"))) 

no he encontrado nada como esto para las asignaciones de fluidez, es posible ?? Las únicas soluciones que se me ocurren son: crear ensamblajes separados para cada clase de asignación de db o agregar explícitamente cada una de las entidades a la configuración de fábrica.

Preferiría evitar ambos, si es posible. Gracias.

+2

Aconsejaría un ensamblado de mapeo por base de datos en esta instancia. Es una buena separación de preocupaciones y debería ser fácil de entender para cualquier otro desarrollador. –

+0

Parece que necesito poner todas las clases en otro proyecto y el otro proyecto en el segundo db. – CallMeLaNN

Respuesta

5

he implementado exactamente esto (la mía) Atributo utilizando en el archivo de asignación Fluido para dictar la que pertenece la entidad dB. Yo también tengo un concepto de una base de datos 'predeterminada', y se supone que los archivos de mapeo sin un atributo residen en la base de datos predeterminada (puede reducir el número de clases que necesita decorar). Luego tengo un código de inicialización que crea una fábrica de sesiones por base de datos, y para cada uno, utiliza la reflexión para encontrar todas las clases de ClassMap, examina el atributo para determinar a qué DB pertenece y registra cada ClassMap en consecuencia.

Un ejemplo de archivo de mapeo:

[FluentNHibernateDatabase("MySecurityDatabase")] 
    public class SystemUserMap : ClassMap<SystemUser> 
    { 
    public SystemUserMap() 
    { 
     Id(x => x.SystemUserId); 
     Map(x => x.LoginId); 
     Map(x => x.LoginPassword); 
     Map(x => x.UserFirstName); 
     Map(x => x.UserSurname); 
     References(x => x.UserOrganisation, "OrganisationId"); 
    } 
    } 

Obviamente he definido una lista de los DB que se hace referencia/usa.
Mi aplicación funciona por lo que yo he tomado, pero he golpeado con un obstáculo (que espero que alguien pueda ayudar con):

le he pedido a mi pregunta aquí: How to identify a particular entity's Session Factory with Fluent NHibernate and Multiple Databases

+3

En este escenario, ¿dónde está haciendo uso del atributo? Sé que estaría en la configuración del mapeo, pero ¿hay alguna posibilidad de que pueda proporcionar más detalles de su implementación? ¡Gracias! – reallyJim

+0

¿Dónde está el atributo FluentNHibernateDatabase y cómo se define Fluently.Configure()? – CallMeLaNN

+0

El atributo es mío y lo uso para identificar la base de datos en la que debe registrarse una clase en particular (el parámetro para el atributo es el nombre que le he dado a mi base de datos). Lo he implementado de modo que tengo lo que considero la base de datos 'predeterminada', y todos los archivos Map que se relacionan con entidades en esa base de datos no necesitan el atributo (o, a la inversa: se supone que todos los archivos de mapas sin el atributo están destinados a el DB predeterminado). – Trevor

1

También puede filtrar por tipos. Aquí hay una línea de código comentado de un "campo verde" AutoPersistenceModel que uso en el mismo ensamblaje que un "campo marrón uno" (es decir, dos bases de datos). Pero solo hay un tipo que necesito filtrar, así que no me he molestado en dividir un ensamblaje heredado. Si tiene muchos de ellos por db, entonces dividirlos por conjuntos probablemente sea la mejor OMI.

Sería fantástico si FNH pudiera proporcionar algún tipo de soporte multi-db integrado, pero no sé cómo se podría hacer realmente; algún tipo de diccionario de SessionFactories tal vez, pero cada situación es única.

HTH,
Berryl

/// <summary> 
    /// This would simply call <see cref="AutoMapHelpers.GetAutoMappingFilter"/> but we need to 
    /// exclude <see cref="LegacyProject"/> also for now. 
    /// </summary> 
    private static bool _getIncludedTypesFilter(Type t) { 
     return _isNotLegacy(t) && AutoMapHelpers.GetAutoMappingFilter(t); 
    } 
    private static bool _isNotLegacy(Type t) { return !t.Equals(typeof(LegacyProject)); } 
4

la manera más fácil de hacer esto es poner el nombre de la base en el esquema

Entonces, a condición de todas las tablas son accesibles en la misma cadena de conexión, sólo necesita una fábrica de sesiones

0

Aunque es una respuesta muy tardía, le sugiero que revise la siguiente URL que, de hecho, tiene alguna solución que resolver y, por lo tanto, puede encontrar la solución en las respuestas. Here es la solución a su respuesta que fue implementado con la ayuda de url

Por la solución implementada por mí sólo se puede aplicar la base de datos primer modelo a partir de ahora. Intente evitar el método GenerateSchema en la pregunta que publique en la URL mencionada, porque aún no está implementado como si utilizara ese método, podrá ver las múltiples bases de datos con las mismas tablas y relaciones creadas.

Cuestiones relacionadas