Entity Framework 5, che separa la business logic dal modello - Repository?

2

Sto lavorando alla mia prima applicazione web pubblica e sto utilizzando MVC 4 per il livello di presentazione e EF 5 per il DAL. La struttura del database è bloccata e vi sono differenze moderate tra il modo in cui l'utente immette i dati e il modo in cui il database stesso viene popolato. Ho fatto un sacco di letture sul pattern del repository (che non ho mai usato) ma la maggior parte della mia ricerca mi sta spingendo a non usarlo poiché presumibilmente crea un livello non necessario di astrazione per le ultime versioni di EF dal momento che repository e unit- di lavoro sono già integrati.

Il mio approccio iniziale è semplicemente creare un set separato di classi per i miei oggetti di business nella BLL che può fungere da intermediario tra i miei Controller e il DAL. Ecco una classe di esempio:

public class MyBuilding
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public string Notes { get; set; }

    private readonly Entities _context = new Entities(); // Is this thread safe?
    private static readonly int UserId = WebSecurity.GetCurrentUser().UserId;

    public IEnumerable<MyBuilding> GetList()
    {
        IEnumerable<MyBuilding> buildingList = 
            from p in _context.BuildingInfo
            where p.Building.UserProfile.UserId == UserId
            select new MyBuilding {Id = p.BuildingId, Name = p.BuildingName, Notes = p.Building.Notes};
        return buildingList;
    }

    public void Create()
    {
        var b = new Building {UserId = UserId, Notes = this.Notes};
        _context.Building.Add(b);
        _context.SaveChanges();

        // Set the building ID
        this.Id = b.BuildingId;

        // Seed 1-to-1 tables with reference the new building
        _context.BuildingInfo.Add(new BuildingInfo {Building = b});
        _context.GeneralInfo.Add(new GeneralInfo {Building = b});
        _context.LocationInfo.Add(new LocationInfo {Building = b});
        _context.SaveChanges();
    }

    public static MyBuilding Find(int id)
    {
        using (var context = new Entities())  // Is this OK to do in a static method?
        {
            var b = context.Building.FirstOrDefault(p => p.BuildingId == id && p.UserId == UserId);
            if (b == null) throw new Exception("Error: Building not found or user does not have access.");
            return new MyBuilding {Id = b.BuildingId, Name = b.BuildingInfo.BuildingName, Notes = b.Notes};
        }
    }
}

La mia preoccupazione principale: è il modo in cui sto istanziando il mio DbContext come proprietà privata thread-safe, ed è sicuro avere un metodo statico che istanzia un DbContext separato? O mi sto avvicinando a questo tutto sbagliato? Non sono contrario all'apprendimento del modello di repository se sto prendendo l'approccio completamente sbagliato qui.

    
posta bnice7 27.10.2013 - 02:02
fonte

1 risposta

3

Poiché lo schema del database è al di fuori del tuo ambito e soggetto a modifiche, è estremamente importante isolarlo dal tuo codice principale. Le operazioni di mappatura e manipolazione delle tabelle che stai chiamando dalle funzioni Create e GetList dovrebbero idealmente risiedere nel tuo DAL. In questo modo, le tue entità e le classi di business logic non saranno interessate da modifiche inaspettate al codice generato da EF. Anche le principali modifiche allo schema del database diventano semplicemente una questione di modifica delle funzioni di mappatura.

Altrimenti, eviterei di avere istanze di entità di business che hanno chiamate per caricare altre istanze del loro tipo - odora la violazione del principio di responsabilità singola, poiché le istanze MyBuikding sono sia oggetti di ricerca dati che entità di dati. Puoi ottenere le tue entità direttamente dalle chiamate ai tuoi archivi DAL o tramite alcune chiamate di livello intermedio se richiedi una logica aziendale.

    
risposta data 27.10.2013 - 21:05
fonte

Leggi altre domande sui tag