2010-01-14 11 views
8

Sto iniziando a lavorare su un nuovo progetto che sarebbe molto più semplice se ci fosse un modo per rendere polimorfici diversi modelli di dati. Sto cercando di usare Entity Framework 4.0 (quando è rilasciato), ma non sono stato in grado di determinare se sarà effettivamente in grado di funzionare.Esiste un .NET Data Framework polimorfico

Ecco lo scenario di base. Sono implementato un sistema di commenti e vorrei poterlo connettere a molti tipi diversi di modelli. Forse voglio commenti sul profilo di una persona e commenti su una pagina web. Il modo in cui lo farei in passato è creare relazioni tra la tabella delle persone e la tabella dei commenti separatamente dalla relazione tra la tabella delle pagine Web e la tabella dei commenti. Penso che questo porti ad una struttura di tabelle troppo complicata nel database, comunque.

Sarebbe meglio se potessi essere in grado di aggiungere un'interfaccia agli oggetti su cui desidero aggiungere commenti e quindi semplificare la struttura della tabella nel database in un'unica relazione.

Il problema che sto incontrando è che non mi sembra di conoscere la terminologia giusta per trovare informazioni su come fare questo tipo di cose. Qualsiasi aiuto che chiunque possa fornire sarebbe molto apprezzato.

risposta

2

Se si progetta il "tavolo commenti" essere commentare tipo agnostico (solo le basi, come un ID, data & tempo, e il contenuto del testo), è quindi possibile usa una singola tabella aggiuntiva che li mappa tutti.

public interface ICommentable 
{ 
    int CommentTypeCode 
    int Id 
    ... 
} 

Ora quel tavolo mapper contiene le colonne:

  • comment_type_code
  • target_object_id
  • COMMENT_ID

vostre osservazioni vanno tutti in una sola tabella, con un ID Your vari " gli oggetti target "devono avere tutti un ID dello stesso tipo

Ora è possibile aggiungere arbitrariamente nuovi oggetti "commentabili" al proprio sistema senza modificare la tabella dei commenti o la tabella del mappatore - basta assegnargli un nuovo codice di tipo e creare la tabella con la colonna Id richiesta.

+0

Sì, questo è esattamente il tipo di cosa a cui stavo pensando. Speravo che potesse esserci un modo per gestire il cast di tipo in modo trasparente, ma sembra che dovrò solo mordere il proiettile e farlo. In questo caso, dovrei controllare il target_object_id, così come il comment_type, che probabilmente sarà solo il System.Type dell'oggetto target. Non ho avuto bisogno di lavorare molto con quello, quindi sembra che imparerò. – Josh

+0

Bene, questo presuppone che il tuo obiettivo è ridurre il numero di tabelle nel tuo database, che ho raccolto dalla domanda originale. Potrei essere propenso a creare invece "tabelle mapper" per ogni tipo di commento, ma mantenere comunque tutti i commenti in una tabella di commenti. Se si dispone di una tabella "post_comments" con una colonna post_id e una colonna comment_id, è possibile eseguire una query quando la propria vista o modello richiede i commenti per un particolare ID post. Non è richiesto il cast di tipo. – Jay

+0

sì, è giusto, per ridurre il numero di tabelle e la quantità di codice che deve essere scritta. In un mondo perfetto, funzionerebbe qualcosa come i mix-in di Ruby, ma non è davvero possibile in C#. Non è un grosso problema, speravo solo che mi mancasse qualcosa. – Josh

2

Realizzo questo con LinqToSql e classi parziali. Per ogni classe che voglio implementare un'interfaccia, vado a creare un file non generato da strumenti che contiene una parte della classe parziale che dichiara la classe per implementare l'interfaccia.

Ad esempio:

codice generato:

// this code is generated by a tool blah blah 
partial class FooComment { 
    // all the generated crap 
    string Author { 
     // ... 
    } 
    // etc 
} 

L'interfaccia:

interface IComment{ 
    string Author{ get; } 
    // etc 
} 

Il mio codice:

// lovingly hand-written by me 
partial class FooComment : IComment { 
} 

Ora, se si vuole lanciare qualsiasi gruppo di FooComments to IComment, noi e il metodo di estensione Cast LINQ:

db.FooComments.Cast<IComment>() 
+0

Sì, questo è il tipo di soluzione a cui stavo pensando.Speravo che potesse esserci un modo per farlo gestendo il tipo di casting in modo trasparente, ma una funzione generica è probabilmente la migliore che otterrò. – Josh