7

Sto usando ASP.NET MVC con Entity Framework 5.È una cattiva pratica filtrare per ID all'interno del pattern del repository

Essenzialmente ogni risultato dell'azione del controller filtra i risultati del db dall'ID azienda degli utenti registrati. Ho appena iniziato a implementare un modello di repository per restituire i modelli anziché filtrare direttamente DbContext dal controller. (Passando la companyID nel repository per filtrare i risultati dei metodi)

Ho la strana sensazione che sia una cattiva pratica farlo, ma non sono riuscito a trovare alcuna informazione sull'argomento. Inserirò qui sotto una versione base del mio codice attuale, apprezzerei qualsiasi informazione sul fatto che si tratti o meno di cattive pratiche, e perché così.

IBookingSystemRepository.cs

public interface IBookingSystemRepository : IDisposable 
{ 
    IEnumerable<Appointment> GetAppointments(); 
    IEnumerable<Appointment> GetAppointments(bool includeDeleted); 
    IEnumerable<Client> GetClients(); 
    IEnumerable<Client> GetClients(bool includeDeleted); 
    void Save(); 
} 

BookingSystemRepository.cs

public class BookingSystemRepository : IBookingSystemRepository 
{ 
    private BookingSystemEntities db; 
    int CompanyID; 

    public BookingSystemRepository(BookingSystemEntities context, int companyID) 
    { 
     this.db = context; 
     this.CompanyID = companyID; 
    } 

    public IEnumerable<Appointment> GetAppointments() 
    { return GetAppointments(false); } 

    public IEnumerable<Appointment> GetAppointments(bool includeDeleted) 
    { 
     return includeDeleted 
      ? db.Appointments.Where(a => a.User.CompanyID == CompanyID) 
      : db.Appointments.Where(a => a.User.CompanyID == CompanyID && a.Deleted.HasValue); 
    } 

    public IEnumerable<Client> GetClients() 
    { return GetClients(false); } 

    public IEnumerable<Client> GetClients(bool includeDeleted) 
    { 
     return includeDeleted 
      ? db.Clients.Where(c => c.CompanyID == CompanyID) 
      : db.Clients.Where(c => c.CompanyID == CompanyID && c.Deleted.HasValue); 
    } 

    public void Save() 
    { 
     db.SaveChanges(); 
    } 

    public void Dispose() 
    { 
     if (db != null) 
      db.Dispose(); 
    } 
} 

TestController.cs

public class TestController : Controller 
{ 
    private BookingSystemEntities db = new BookingSystemEntities(); 

    public ActionResult AppointmentsList() 
    { 
     var user = db.Users.Single(u => u.Email == User.Identity.Name); 
     IBookingSystemRepository rep = new BookingSystemRepository(db, user.CompanyID); 
     return View(rep.GetAppointments()); 
    } 
} 

Grazie in anticipo per la vostra assistenza :)

risposta

4

Si tratta di un'applicazione multi-tenant. Il filtraggio è necessario per mantenere separati i dati di ciascuna azienda. Il tuo approccio è solido; se possibile, fornire un contesto che è già filtrato, anziché filtrare singolarmente nei metodi del repository downstream.

+0

Grazie mille per il tuo aiuto e una rapida risposta :) Non ho nemmeno pensato di filtrare il contesto prima di passarlo al repository, penso che il tuo approccio renderà le cose ancora più semplici per me! Giusto per chiarire però, intendi per me creare una nuova classe DbContext che filtri tutti i DbSet basati su un ID passato al costruttore? –

+1

Sarebbe un'idea interessante. Sarebbe bello se tu potessi tirarlo fuori. No, stavo pensando più a una repository oa una classe DBContextWrapper che avrebbe alimentato il tuo normale repository. Dal punto di vista della sicurezza, il modo migliore per alimentare DBContext consiste nel fornire Visualizzazioni nel motore del database che sono già filtrate. Ma non so quanto tempo hai. :) –

+0

Quindi essenzialmente creare un altro repository, tra questo e DbContext, che filtra tutto a livello aziendale? La tua idea di filtrarlo usando le viste del database è probabilmente l'opzione migliore, ma non ho il tempo di farlo al momento. Comunque, molte grazie per il vostro aiuto Robert. :) –