webentwicklung-frage-antwort-db.com.de

Verwenden von DbContext Setzen Sie <T> (), anstatt den Kontext anzuzeigen

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?

22
Dismissile

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>.

14
Servy

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.

5
PinnyM

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.

2
maicalal

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 TUser ist)

2
Travis J

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.

0
Behnam Esmaili