2012-12-04 6 views
18

Ci sono differenze quando si fa il seguente:Utilizzando DbContext Set <T>() invece di esporre sul contesto

public class UsersContext : DbContext 
{ 
    public DbSet<User> Users { get; set; } 
} 

contro utilizzando il metodo Set<T> del contesto:

public class UsersContext : DbContext 
{ 
} 

var db = new UsersContext(); 
var users = db.Set<User>(); 

Questi effettivamente fanno la stessa cosa, dandomi un insieme di utenti, ma ci sono grandi differenze se non esponendo il set attraverso una proprietà?

+0

@abatishchev http://msdn.microsoft.com/en-us/library/gg696521(v=vs.103).aspx No c'è un metodo Set Dismissile

+0

Certo, grazie, sciocco me :) – abatishchev

risposta

10

La proprietà Users viene aggiunta per comodità, quindi non è necessario ricordare cosa tutti le nostre tabelle sono e qual è la classe corrispondente, puoi usare Intellisense per vedere tutte le tabelle con cui il contesto è stato progettato per interagire. Il risultato finale è funzionalmente equivalente all'uso di Set<T>.

+1

Gli utenti potrebbero essere solo un'istanza mentre si trova nel contesto, mi chiedo come impostare il metodo, restituire anche l'istanza singola? –

5

Si ottiene un vantaggio con il metodo precedente quando si utilizzano le migrazioni Code-First, poiché le nuove entità verranno rilevate automaticamente. Altrimenti, sono abbastanza certo che siano equivalenti.

+0

ho fatto non pensare alle migrazioni! – Dismissile

0

ritengo non esiste differenza tra due approcci tranne che Set<User>() è più adatto per implementare schemi di accesso dati come Repository modello a causa della natura generica del metodo Set<T>().

+0

Sì, capisco dove hanno i loro usi per un repository generico, ma ero curioso di sapere se c'erano degli svantaggi. – Dismissile

+0

Ma c'è anche un generico DbSet , e ora ??? – Legends

2

è così che ho impostato la mia generica dbSet, funziona bene

DbContext context = new MyContext(); 
DbSet<T> dbSet = context.Set<T>(); 

E 'la versione generica di qualcosa di più esplicito, come ad esempio

DbContext context = new MyContext(); 
DbSet<User> dbSet = context.Set<User>(); 

In entrambi i casi, sono gli stessi (quando T è User)

+0

Err ... okay? Capisco come funziona. Volevo sapere quali sono le differenze/limitazioni. – Dismissile

+2

@Dismissile - Nessuna limitazione o differenza, ad eccezione del fatto che potresti risparmiare del codice ripetuto utilizzando la definizione generica e passando il tipo. –

+0

Set <> deve essere restituito sempre a istanza singola per indicare limitazioni o differenze, giusto? –

2

Penso che ci sia qualche differenza. Lasciami usare l'esempio come nella domanda. Si supponga che voglio fare una qualsiasi base di User.FirstName e User.LastName (tabella utente ha più campi)

Method1: UsersContext.Users.Any(u => u.FirstName.ToLower() == userObj.FirstName && u.LastName.ToLower() == userObj.LastName);

Method2: (UsersContext.Set(typeof(User)) as IQueryable<User>).Any(u => u.FirstName.ToLower() == userObj.FirstName && u.LastName.ToLower() == userObj.LastName);

ho controllato profiler SQL query sparato in Method1 è:

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' 

Da Method2:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[FirstName] AS [FirstName], 
[Extent1].[LastName] AS [LastName], 
[Extent1].[Email] AS [Email], 
.......other fields...... 
FROM [dbo].[Users] AS [Extent1] 

La tabella ha 40000 record e Method1 richiede circa 20 ms mentre Method2 richiede circa 3500 ms.

+0

Set può prendere un parametro generico. Prova Set (). Any (...) – Dismissile

+0

@Dismissile Ho provato Set (). Any() e ha lo stesso comportamento. – maicalal

+0

Allora stai facendo qualcosa di strano, perché tutti e tre i metodi producono la stessa esatta query per me. – Dismissile

Problemi correlati