Best practice per la modellazione di un'entità di registrazione attiva che utilizza Linq-To-SQL come DAL

2

Attualmente sto avviando un nuovo sistema sulla mia azienda e stiamo utilizzando una buona separazione tra modelli, viste e controllori, fondamentalmente usando Asp.Net MVC 3 per l'interfaccia utente utente e una libreria di classi C # per il modello.

La domanda riguarda la "modellazione di un modello".

Stiamo utilizzando Linq-to-SQL come livello di accesso ai dati e modellazione di entità su questo DAL. Esempio:

    // DAL, an autogenerated .dbml file
    ...
    public System.Data.Linq.Table<TB_USER> TB_USERs {
       get {
          return this.GetTable<TB_USER>();
       }
    }
    ...

E stiamo mappando questa tabella su un'entità, come di seguito:

    public class User {
       // Entity, mirroring a .dbml table
       public static IEnumerable<User> GetAll() {
           var db = new MyDataContext();
           var userList = (from u in db.TB_USERs select u).ToList();
           IEnumerable<User> retorno = lista.ConvertAll(u => (User)u);
           return retorno;
       }

       // Active Record ?
       public static User Save(User user) { ... }
    }

Questo tipo di modellazione è corretta? Mi sento come se stessi ripetendo me stesso avendo due entità che significano la stessa cosa (Utente e TB_USER), ma TB_USER è la rappresentazione grezza della tabella del database che persiste nell'entità Utente.

E il metodo GetAll, un metodo statico creato sull'entità con l'unico scopo di recuperarli tutti. Ciò significa che se voglio recuperare i dati utilizzando un filtro, ad esempio, devo creare un altro metodo GetDataBy... .

E il metodo Save? So che si suppone di salvare lo stato di un utente, ma cosa succede se devo salvare un oggetto utente casuale insieme ad altri oggetti per effettuare una transazione?

Non dovrebbe questo tipo di controllo delle transazioni essere nel database?

    
posta Machado 21.12.2011 - 19:36
fonte

2 risposte

2

Se si intende attenersi a LINQ-to-SQL, si consiglia di utilizzare le classi linq-to-sql come entità. Si tratta di rinominare TB_USER in Utente e quindi avvolgere l'interazione con LINQ-to-sql nei repository, ovvero un UserRepository con GetById, GetByUserName, Save e metodi simili, in base alle proprie esigenze specifiche. Ciò mantiene l'accesso ai dati in un unico posto.

Con LINQ-to-sql fai attenzione alla tentazione di avere espressioni LINQ che si spengono e interrogare il DB sparsi sul tuo codice base. LINQ-to-sql sembra incoraggiarlo nella mia esperienza. Ma questo porta a un accoppiamento molto stretto.

Se vuoi un taglio più pulito tra le entità del tuo dominio e il DB, ti consiglio di passare a un altro ORM. La mia preferenza personale con un server SQL sul back-end sarebbe NHibernate.

    
risposta data 21.12.2011 - 23:49
fonte
0

Penso che Christian abbia trovato una buona risposta alla tua domanda. Sulla base dei commenti scambiati potrebbero esserci alcune cose che vale la pena di spiegare nel modello che si tenta di usare.

POCO è il suo nome. Semplici oggetti puri che non hanno alcuna logica dentro. Sono solo concessioni di getter / setter che vuoi esporre al, nel caso descritto, interfaccia utente. Il repository è una classe aggiuntiva che è il posto per la logica dei dati tra DAL e la presentazione. Questo visto insieme agli oggetti ORM, sì, ci sono molte classi coinvolte. Tuttavia, le classi ORM non sono altro che il designer UML di cui occuparsi. Le classi Repo e poco sono più interessanti perché vanno all'interfaccia tra il tuo ORM e la tua interfaccia utente.

vale a dire. Posso avere un residente denominato POCO, che può avere campi provenienti da più tabelle (oggetti Entity) in DAL. Cioè Posizione per l'indirizzo e le specifiche dell'appartamento e anche Utente, che contiene il nome, indirizzo email e tali informazioni. L'interfaccia utente non saprà mai che esiste un design per la tabella degli utenti. A volte i Pocos possono ripetere la ripetizione dello stesso oggetto (perché contengono gli stessi campi dell'interfaccia utente del DAL).

Corretti i metodi GetAll (), Save (), dovrebbero essere nella classe repo. Cioè Save () potrebbe essere Save (PocoType poco), che all'interno del metodo, memorizza l'oggetto poco nei corrispondenti campi di entità DAL. GetAll () restituisce l'oggetto poco, all'interno del metodo ci sono la logica per aprire DAL, recuperare i dati e trasformarli nel tipo POCO.

Anch'io, a volte, uso un oggetto IEnumerable SomeEntity {get {..}} che all'interno del getter apre il DAL e si trasforma in PocoType. Dall'interfaccia utente ho un contesto linq completamente disponibile. come var result = instantiatedType.SomeEntity.Where(u=>u.LoggedIn > DateTime.Now.AddDays(365)) (ho preso questo da capo, potrei aver perso alcuni dettagli sulla sintassi).

Ok spero di aver aggiunto qualcosa di utile e, almeno, informazioni corrette :). È nel bel mezzo della notte e il giorno di Natale è arrivato!

    
risposta data 24.12.2011 - 00:08
fonte

Leggi altre domande sui tag