2016-08-30 5 views
1

Ich habe eine DbContext Hilfsklasse, die Erweiterung Methoden verwendet:EF6 DbContext Erweiterungsmethoden, die Threadsicherheit

public static class DBContextHelper 
{ 
    public static async Task<T> FindAsync<T>(
     this DBContext context, 
     Expression<Func<T, bool>> match) 
     where T : BaseEntity 
    { 
     return await context.Set<T>().SingleOrDefaultAsync(match); 
    } 
} 

Sind Erweiterungsmethoden eine schlechte Passform für diesen, da sie möglicherweise von verschiedenen Threads Problemen verursacht zugegriffen werden?

Antwort

1

Extensions-Methoden können Thread-sicher sein, und Thread kann unsicher sein, je nachdem, wie Sie sie schreiben.

Ihre Methode ist Thread-sicher, während jeder DbContext von anderen Thread zugegriffen wird. Das ist eine vernünftige Einschränkung, denn DbContext ist nicht wirklich thread-sichere Klasse. (Aktivieren Sie Multiple Active Result Sets Sie können diese Einschränkung entfernen, aber es ist keine gute Entscheidung Ursache DbContexttracks data).

Es ist gut, Praxis DbContext für einen einzelnen Geschäftsbetrieb zu schaffen und sofort entsorgen - es ist die way of the Unit Of Work pattern ist.

F.e. in Web-API-Szenario können Sie verschiedene DbContext für jede HTTP-Anforderung erstellen oder sogar können Sie verschiedene Rahmen für jede Operation erstellen:

public class UserRepository : IUserRepository 
{ 
    public User async GetByIdAsync(int id) 
    { 
     using (var dbContext = new MyDbContext()) 
     { 
      var data = await dbContext.FindAsync((UserData user) => user.Id == id); 

      return new User(data); 
     } 
    } 
} 

Verfahren FindAsync korrekt in diesem Code funktioniert, auch wenn es nicht bequem zu nennen ist. Ich würde die Signatur ändern:

public static class DBSetHelper 
{ 
    public static async Task<T> FindAsync<T>(
     this DbSet<T> set, 
     Expression<Func<T, bool>> match) 
     where T : BaseEntity 
    { 
     return await set.SingleOrDefaultAsync(match); 
    } 
} 

. . . 

public class UserRepository : IUserRepository 
{ 
    public User async GetByIdAsync(int id) 
    { 
     using (var dbContext = new MyDbContext()) 
     { 
      var data = await dbContext.Users.FindAsync(user => user.Id == id); 

      return new User(data); 
     } 
    } 
} 
Verwandte Themen