Domanda

Sono nel processo di costruzione la mia prima applicazione web utilizzando ASP.NET MVC 2 e Entity Framework. Sto usando il modello repository. Da informazioni che ho raccolto su Stack Overflow e altri siti web sembra che il consenso è di avere un un controller per oggetto modello di dominio e un repository per oggetto principale di aggregazione.

La domanda che ho è come dovrei essere accesso non root oggetti aggregati attraverso il repository radice aggregato. Nell'esempio ho a che fare con c'è un modello del cliente e un modello barca. Le barche possono esistere solo con un riferimento FK ad un Cliente e barche sufficiente che si trovino riferimento nel contesto di un cliente. Questo mi ha portato a credere che ho avuto un aggregato con questi due oggetti e che il Cliente è stata la radice.

Ora nei miei Barche controllore Ho un metodo di azione Modifica:

public class BoatsController : Controller
{
    private ICustomersRepository customersRepository;
    public BoatsController(ICustomersRepository customersRepository)
    {
        this.customersRepository = customersRepository;
    }   
    public JsonResult Edit(int id, FormCollection collection)
    {
        var boat = customersRepository.GetBoat(id);
        // Update boat
    }
}

La mia domanda è come io voglio recuperare l'oggetto barca nel repository?

public class SQLCustomersRepository : ICustomersRepository
{
    DatabaseEntities db = new DatabaseEntities();

    public Boat GetBoat(int id)
    {
        return db.Boats.SingleOrDefault(x => x.ID == id);

        // OR

        return db.Customers.Where(x => x.Boats.Any(y => y.ID == id)
                           .Select(x => x.Boats.FirstOrDefault(y => y.ID == id);
    }
}

E 'accettabile per me db.Boats di riferimento dai Clienti repository? Sembra essere il più pulito, ma vorrebbe dire che avrei dovuto alterare il mio FakeCustomersRepository di avere un elenco di clienti e barche.

E 'sembrato più ragionevole per me per accedere alla barca attraverso db.Customers, tuttavia, non riuscivo a capire come restituire un singolo oggetto barca senza ripetermi nella query LINQ che in realtà non ha fatto mi sta bene.

So che ho ancora molto da imparare quindi speriamo che mi può puntare nella direzione giusta!

Grazie!

È stato utile?

Soluzione

A mio parere si sta parlando di dettagli di implementazione, non circa le interfacce astratte e il vostro modello. L'interfaccia sembra simile a questa:

public interface ICustomersRepository
{
    //... other methods
    Boat GetBoat(int id);
    //... other methods
}

e il modello in questo modo:

public class Customer
{
    //... other stuff
    ICollection<Boat> Boats; // or another collection type
    //... other stuff
}

Ho il mio parere non è contro tutte le regole di progettazione per l'attuazione del ICustomerRepository completamente diversa per il vostro SQLCustomersRepository e per la vostra FakeCustomersRepository e di trovare un'implementazione che è ottimale rispetto al tuo dati sottostante.

Dal momento che ti sembra di avere una chiave primaria nella tabella Barca in SQL-DB avrei assolutamente approfittare di questo e implementare la prima opzione: return db.Boats.SingleOrDefault(x => x.ID == id);

Ma non è necessario avere una collezione di barche nella vostra FakeCustomersRepository. Se è più facile per voi solo per avere un elenco di clienti e di popolare la raccolta Barche in ciascun cliente con le barche di prova, perché no? In questo caso l'implementazione GetBoat nel FakeCustomersRepository potrebbe essere attuato con la seconda query LINQ che hai descritto.

Tieni presente che Unit testing in MVC non intende testare le vostre specifiche implementazioni di repository, ma la logica di business, e un'azione di business è più una catena di vari oggetti di dominio e chiamate di metodo repository. Se un singolo metodo repository fa quello che deve fare (per esempio se GetBoat davvero restituisce una barca con l'ID corretto) è più una questione di un test di integrazione in seguito per dimostrare che le chiamate di database funzionino correttamente.

Altri suggerimenti

Perché non si dispone di un repository barca?

Se l'imbarcazione è un AggRoot allora si dovrebbe avere un repository separato per questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top