7

Obecnie tworzymy aplikację opartą na NHibernate i ASP.NET MVC oraz backend serwera SQL. Ponieważ jestem całkiem nowy w NHibernate, staram się zrozumieć najlepsze praktyki.nHibernate, ASP.NET MVC, architektura s # arp i wiele identycznych baz danych

Nasza aplikacja wymaga od każdego użytkownika posiadania własnej bazy danych SQL Server. Wszystkie te bazy danych mają identyczną strukturę.

Nasi klienci są identyfikowani za pomocą kodu klienta, np. 1500.

Musimy wymyślić dostawcy niestandardowego połączenia dla nHibernate, którą już wykorzystać w naszych nServiceBus usług backend:

public class DynamicConnectionProvider : DriverConnectionProvider 
{ 
    public override IDbConnection GetConnection() 
    { 
     IDbConnection conn = Driver.CreateConnection(); 

     try 
     { 
      var messageExecutionContext = ServiceLocator.Current.GetInstance<ITTTContextProvider>().CurrentContext; 
      if (messageExecutionContext.CustomerId == 0) 
      { 
       conn.ConnectionString = ConfigurationManager.ConnectionStrings["dev"] 
        .ConnectionString; 
      } 
      else 
      { 
       conn.ConnectionString = ConfigurationManager.ConnectionStrings["default"] 
        .ConnectionString 
        .FormatWith(messageExecutionContext.CustomerId); 
      } 

      conn.Open(); 
     } 
     catch (Exception) 
     { 
      conn.Dispose(); 
      throw; 
     } 
     return conn; 
    } 
} 

Ten dostawca połączenie sprawdza kod klienta w obiekcie kontekstowego i ustawia odpowiednio połączenie.

Planujemy dostarczyć HttpContext świadomy ITTTContextProvider. W tym celu mam dwa pytania:

  1. Jak możemy pobrać kod klienta z adresu URL i umieścić go w naszym obiekcie kontekstowym dla każdego żądania? kiedy używamy następującej trasy?

    <main-site-url>/{customercode}/{controller}/{action}/{id}

  2. Czy ta metoda łączenia się z kilku identycznych baz ważne czy jest to lepsza praktyka skonstruować SessionFactory bazy foreach klienta?

Odpowiedz

1

W celu uzyskania jak customercode trzeba uzyskać dostęp do danych tras, coś wzdłuż linii

HttpContextBase currentContext = new HttpContextWrapper(HttpContext.Current); //ServiceLocator.Current.GetInstance<ITTTContextProvider>().CurrentContext; 
RouteData routeData = RouteTable.Routes.GetRouteData(currentContext); 
var cusomterCode = routeData.Values["customercode"] 

mój drugi sugestią byłoby nie umieścić ten kod w powyższym fragmencie usług. Rozwiń to. Zobacz Joshua's answer, która podkreśla podejście, o którym myślę.

Naprawdę nie mogę pomóc w drugim pytaniu, właściwie nieznajomym obu wspomnianych ram.

+1

Początkowo odpowiedź - z tego co pamiętam do tworzenia fabryki sesji jest kosztowna operacja, która jest chyba coś, co będzie czynnikiem w decyzji. Biorąc pod uwagę, że istnieje wiele baz danych, a także zależy od oczekiwanej liczby trafień w bazie danych, może to być kluczowy czynnik. Czy fabryki sesyjne nie mają korzyści, takich jak buforowanie itp., Które mogą być przydatne w twojej sytuacji? To może być pomocne - http://www.codeproject.com/KB/aspnet/NHibernateMultipleDBs.aspx – Ahmad

+0

Buforowanie to coś, czego będziemy potrzebować w przyszłości. Jednak w jaki sposób jest wdrażane buforowanie na drugim poziomie? Per SessionFactory lub na połączenie (ciąg)? – Rik

+0

@Rik - przepraszam, ponieważ powiedziałem, że nie jestem zbyt zaznajomiony i nie mam wystarczająco dużo rąk do doświadczenia z jakąkolwiek strukturą – Ahmad