Domyślna aplikacja MVC 5 zawiera ten fragment kodu w IdentityModels.cs - ten fragment kodu dotyczy wszystkich operacji związanych z tożsamością ASP.NET dla domyślnych szablonów:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
Jeśli rusztuję nowego kontrolera za pomocą widoków z Entity Framework i utworzę „Nowy kontekst danych ...” w oknie dialogowym, otrzymam to dla mnie:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace WebApplication1.Models
{
public class AllTheOtherStuffDbContext : DbContext
{
// You can add custom code to this file. Changes will not be overwritten.
//
// If you want Entity Framework to drop and regenerate your database
// automatically whenever you change your model schema, please use data migrations.
// For more information refer to the documentation:
// http://msdn.microsoft.com/en-us/data/jj591621.aspx
public AllTheOtherStuffDbContext() : base("name=AllTheOtherStuffDbContext")
{
}
public System.Data.Entity.DbSet<WebApplication1.Models.Movie> Movies { get; set; }
}
}
Jeśli rusztuję inny kontroler + widok za pomocą EF, powiedzmy na przykład dla modelu Animal, ta nowa linia zostanie automatycznie wygenerowana pod public System.Data.Entity.DbSet<WebApplication1.Models.Movie> Movies { get; set; }
- tak jak poniżej:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace WebApplication1.Models
{
public class AllTheOtherStuffDbContext : DbContext
{
// You can add custom code to this file. Changes will not be overwritten.
//
// If you want Entity Framework to drop and regenerate your database
// automatically whenever you change your model schema, please use data migrations.
// For more information refer to the documentation:
// http://msdn.microsoft.com/en-us/data/jj591621.aspx
public AllTheOtherStuffDbContext() : base("name=AllTheOtherStuffDbContext")
{
}
public System.Data.Entity.DbSet<WebApplication1.Models.Movie> Movies { get; set; }
public System.Data.Entity.DbSet<WebApplication1.Models.Animal> Animals { get; set; }
}
}
ApplicationDbContext
(dla wszystkich elementów tożsamości ASP.NET) dziedziczy, z IdentityDbContext
których z kolei dziedziczy DbContext
.
AllOtherStuffDbContext
(dla moich własnych rzeczy) dziedziczy DbContext
.
Więc moje pytanie brzmi:
Którego z tych dwóch ( ApplicationDbContext
i AllOtherStuffDbContext
) powinienem używać dla wszystkich innych moich modeli? A może powinienem po prostu użyć domyślnej funkcji automatycznego generowania, ApplicationDbContext
ponieważ nie powinno to stanowić problemu, ponieważ pochodzi ona z klasy podstawowej DbContext
, czy też będzie jakiś narzut? Należy używać tylko jeden DbContext
obiekt w swojej aplikacji dla wszystkich modeli (czytałem to gdzieś), więc nie powinien nawet rozważyć zastosowanie zarówno ApplicationDbContext
i AllOtherStuffDbContext
w jednej aplikacji? Lub jaka jest najlepsza praktyka w MVC 5 z ASP.NET Identity?
źródło
Odpowiedzi:
Użyłbym pojedynczej klasy Context dziedziczącej po IdentityDbContext. W ten sposób kontekst może być świadomy wszelkich relacji między twoimi klasami a IdentityUser i rolami IdentityDbContext. IdentityDbContext ma bardzo niewielki narzut, jest to w zasadzie zwykły DbContext z dwoma zestawami DbSet. Jeden dla użytkowników i jeden dla ról.
źródło
Istnieje wiele nieporozumień na temat IdentityDbContext , szybkiego wyszukiwania w Stackoverflow, a znajdziesz następujące pytania:
„ Dlaczego Asp.Net Identity IdentityDbContext jest czarną skrzynką?
Jak mogę zmienić nazwy tabel podczas korzystania z Visual Studio 2013 AspNet Identity?
Scal MyDbContext z IdentityDbContext ”
Aby odpowiedzieć na wszystkie te pytania, musimy zrozumieć, że IdentityDbContext jest tylko klasą odziedziczoną po DbContext.
Rzućmy okiem na źródło IdentityDbContext :
Jeśli chcemy połączyć IdentityDbContext z naszym DbContext, mamy do wyboru dwie opcje:
Pierwsza opcja:
Utwórz DbContext, który dziedziczy z IdentityDbContext i ma dostęp do klas.
Dodatkowe uwagi:
1) Możemy również zmienić domyślne nazwy tabel asp.net Identity za pomocą następującego rozwiązania:
2) Ponadto możemy rozszerzyć każdą klasę i dodać dowolną właściwość do klas takich jak „IdentityUser”, „IdentityRole”, ...
Aby zaoszczędzić czas, możemy użyć rozszerzalnego szablonu projektu AspNet Identity 2.0, aby rozszerzyć wszystkie klasy.
Druga opcja:(Niezalecane) W
rzeczywistości nie musimy dziedziczyć po IdentityDbContext, jeśli sami piszemy cały kod.
Więc w zasadzie możemy po prostu odziedziczyć DbContext i zaimplementować naszą dostosowaną wersję „OnModelCreating (ModelBuilder builder)” z kodu źródłowego IdentityDbContext
źródło
Jest to późny wpis dla ludzi, ale poniżej znajduje się moja implementacja. Zauważysz również, że wyeliminowałem możliwość zmiany domyślnego typu KLUCZA: szczegóły na ten temat można znaleźć w następujących artykułach:
UWAGI:
Należy zauważyć, że nie można używać
Guid's
kluczy. Wynika to z faktu, że pod maską są oneStruct
i jako takie nie mają rozpakowywania, co pozwoliłoby na ich konwersję z generycznego<TKey>
parametru .KLASY WYGLĄDAJĄ:
źródło
Po przejrzeniu abstrakcji IdentityDbContext przekonasz się, że wygląda ona podobnie do pochodnej DbContext. Najłatwiejszą drogą jest odpowiedź Olava, ale jeśli chcesz mieć większą kontrolę nad tym, co się tworzy, i trochę mniej zależności od pakietów tożsamości, spójrz na moje pytanie i odpowiedź tutaj . Istnieje przykładowy kod, jeśli podążysz za linkiem, ale w podsumowaniu po prostu dodajesz wymagane DbSets do własnej podklasy DbContext.
źródło