Gibt es Unterschiede, wenn Sie Folgendes tun:
public class UsersContext : DbContext
{
public DbSet<User> Users { get; set; }
}
im Vergleich zur Set<T>
-Methode des Kontextes:
public class UsersContext : DbContext
{
}
var db = new UsersContext();
var users = db.Set<User>();
Diese machen zwar dasselbe und geben mir eine Reihe von Benutzern, aber gibt es große Unterschiede, außer dass Sie das Set nicht über eine Eigenschaft verfügbar machen?
Die Users
-Eigenschaft wurde zur Vereinfachung hinzugefügt. Sie müssen sich also nicht daran erinnern, was alle Ihre Tabellen sind und welche Klasse sie dafür haben. Sie können Intellisense verwenden, um alle Tabellen anzuzeigen, mit denen der Kontext interagiert wurde. Das Endergebnis entspricht funktional der Verwendung von Set<T>
.
Bei der vorherigen Methode profitieren Sie von der Verwendung der Code-First-Migrationen, da neue Entitäten automatisch als solche erkannt werden. Ansonsten bin ich mir ziemlich sicher, dass sie gleichwertig sind.
Ich denke, da gibt es einen Unterschied ... Lasst mich das Beispiel wie in der Frage verwenden. Angenommen, ich möchte ein Any auf Basis von User.FirstName und User.LastName (User-Tabelle hat mehr Felder)
Methode1: UsersContext.Users.Any(u => u.FirstName.ToLower() == userObj.FirstName && u.LastName.ToLower() == userObj.LastName);
Methode2: (UsersContext.Set(typeof(User)) as IQueryable<User>).Any(u => u.FirstName.ToLower() == userObj.FirstName && u.LastName.ToLower() == userObj.LastName);
Ich habe im SQL-Profiler die in Methode1 ausgelöste Abfrage eingecheckt:
exec sp_executesql N'SELECT
CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[User] AS [Extent1]
WHERE (((LOWER([Extent1].[FirstName])) = (LOWER(@p__linq__0))) AND ((LOWER([Extent1].[LastName])) = @p__linq__1)
)) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[User] AS [Extent2]
WHERE (((LOWER([Extent2].[FirstName])) = (LOWER(@p__linq__0))) AND ([Extent2].[LastName] = @p__linq__1)
)) THEN cast(0 as bit) END AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]',@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',@p__linq__0=N'jack',@p__linq__1=N'saw'
Von Methode2:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Email] AS [Email],
.......other fields......
FROM [dbo].[Users] AS [Extent1]
Die Tabelle enthält 40000 Datensätze, und Method1 dauert etwa 20 ms, während Method2 etwa 3500 ms benötigt.
So setze ich mein generisches dbSet ein, funktioniert einwandfrei
DbContext context = new MyContext();
DbSet<T> dbSet = context.Set<T>();
Es ist die generische Version von etwas expliziterem, wie zB
DbContext context = new MyContext();
DbSet<User> dbSet = context.Set<User>();
In beiden Fällen sind sie gleich (wenn T
User
ist)
Ich denke, es gibt keinen solchen Unterschied zwischen zwei Ansätzen, außer dass Set<User>()
aufgrund der generischen Natur der Set<T>()
-Methode für die Implementierung von Datenzugriffsmustern wie Repository
pattern besser geeignet ist.