ВведенияASP.NET MVC на несколько Арендатор приложения с несколькими базами данных
я работаю над приложением несколько квартиросъемщиков, что я программирование в ASP.NET MVC с EF6 и Sql Server.
Моя структура базы данных:
1 базовой база данных, которая содержит свойство арендатора (например, имя/поддомен/Каталог).
(Catalog этого имя его присвоенные баз данных)
1 базы данные для каждого клиента
Для зная арендатора я использую поддомен поиск:
- например http://customer1.app.site.com
- например http://customer2.app.site.com
- например http://customer3.app.site.com
Entity Framework
базы и базы данных приложения по умолчанию я добавил файл в ADO.NET Entity data model
(EDMX).
Контроллеры
Чтобы получить правильный жилец я создал новый пользовательский контроллер, который переопределяет метод OnActionExecuting
. Если арендатор существует, я добавляю идентификатор арендатора к переменным маршрута.
// Override OnActionExecuting method which is called every time before the action is called
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var fullAddress = filterContext.HttpContext.Request.Headers["Host"].Split('.');
if (fullAddress.Length < 3)
{
// some code....
}
else
{
var tenantSubdomain = fullAddress[0];
Account currentTenant = db.Accounts.FirstOrDefault(t => t.Subdomain.Equals(tenantSubdomain, StringComparison.CurrentCultureIgnoreCase));
if (currentTenant != null)
filterContext.RouteData.Values["tenant"] = currentTenant.Id;
else
filterContext.Result = new HttpStatusCodeResult(404);
}
base.OnActionExecuting(filterContext);
}
До сих пор все работает нормально. Теперь я застреваю для создания и хранения соединения с назначенной базой данных арендаторов.
Для подключения к базе данных мне нужно использовать следующий код:
public SkycountAppEntities dbApp = new SkycountAppEntities(GetConnString(tenant.Catalogue));
//GetConnString renders the connectionstring which includes the tenants catalogue.
Но где же я отношу эту линию, так что я не должен называть это в каждом действии? Или я могу кэшировать его где-нибудь вместе с cookie аутентификации?
Может ли кто-нибудь вести меня в правильном направлении?
UPDATE
Таким образом, его рабочий, но теперь я должен создать соединение в каждом действии каждого контроллера.
// POST: Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login([Bind(Include = "Username,Password")] User user, string returnUrl)
{
using (SkycountAppEntities dbApp = new SkycountAppEntities(DbEntityFramework.RenderConnectionString(_SkycountAccount.Catalog)))
{
User _user = dbApp.Users.FirstOrDefault(u => u.Username.Equals(user.Username));
if(_user != null && _user.Active && Crypto.VerifyHashedPassword(_user.Password, user.Password))
{
FormsAuthentication.SetAuthCookie(user.Username, false);
if (String.IsNullOrEmpty(returnUrl) || !Url.IsLocalUrl(returnUrl))
return RedirectToAction("Index", "Home");
else
return Redirect(returnUrl);
} else
{
TempData["failed"] = true;
return RedirectToAction("Login", new { returnUrl = returnUrl });
}
}
}
Вы должны изучить и понять инъекцию зависимости. – DarthVader