3

Ich mache eine Intranet-Website mit ASP.NET MVC und SQL Server 2012. Ich mache ein Repository und Architektur mit Zwiebel-Architektur. Mein Problem ist, dass die Firma, in der ich arbeite, bereits mehrere Server-DBs hat, in denen die Tabellen keine Beziehungen zueinander haben. Stattdessen gibt es Tabellen, um diese Beziehungen abzubilden. Beispielsweise haben eine Tabelle Benutzer und eine Tabelle Dokument eine Tabelle User_joint_Document, um eine Beziehung herzustellen, die beide IDs (IDDocument und IDUser) enthält. Nun, wenn ich meine generische Repository schreiben:Entity Framework und Repository Pattern konzeptionelle Schwierigkeiten

class Repository<T> : IRepository<T> where T : class 

das Problem ist der generische Typ T keinen Sinn macht, und ich kann nicht Wert in meinem Modell beeinflusst EF-Abfragen mit was normal ist und was wäre toll wäre, eine Elternklasse BaseEntity haben IDs für jede Tabellen definiert haben, dann kann ich schreiben:

class Repository<T> : IRepository<T> where T : BaseEntity 

Und alle meine Tischmodelle von BaseEntity erben würde. Das würde aber auch bedeuten, die gesamte DB relational zu schreiben und jedes DB-POCO manuell zuzuordnen (korrigiere mich, wenn ich falsch liege), und ich habe nicht die nötigen Fähigkeiten (es gibt über 300 Tabellen in den verschiedenen Server-DBs) und mir fehlt das richtige Wissen und Erfahrung, um diese Art von Operation zu machen).

Gibt es eine Möglichkeit, meine ursprüngliche DB-Struktur zu behalten und trotzdem ein generisches Repository zu schreiben? Wie würde man das machen?

BEARBEITEN Um meine Frage zu klären, weil @saeb teilweise auf meine Frage antwortete. Kann ich einen generischen Repo haben, ohne eine Elternklasse für meine DB POCOs zu haben? Oder brauche ich es, um dann nur noch ein Repository zu haben, um alle zu beherrschen? Zum Beispiel:

class Repository<T>:IRepository<T> where T : class 
{ 
    private readonly ApplicationContext context; 
    private DbSet<T> entities; 
    public Repository(PrincipalServerContext context) 
    { 
     this.context = context; 
     entities = context.Set<T>(); 
    } 
    public T Get(long id) 
    { 
    return entities.SingleOrDefault(s => s.IDUser == id); 
    //This does not work, IDUser isn't recognized 

    } 

Vielen Dank für Ihre Hilfe!

+0

Das Beispiel, das Sie von 'Benutzer' gegeben haben und 'Dateien' korrekt in der Datenbank. Ein Benutzer kann viele Dokumente haben, so dass Sie eine Junction-Tabelle von 'User_joint_Document' benötigen. So sollte eine relationale Datenbank strukturiert sein. – melkisadek

+1

Aber wenn Sie Onion Architecture verwenden, gibt es ein Paket, das automatisch Repositories für Sie erstellt, Sie müssen sie nur in DataOnion registrieren. –

+0

@melkisadek Bah! So schlecht arbeite ich an DBs. Ich hätte gedacht, du hättest zwischen den beiden Tischen so etwas wie eine 1-1-Beziehung oder so etwas? Vielleicht ist das Rel'ship ein echter Tisch? Wirklich nicht meine starke Seite. Wenn ich eine Elternklasse mit IDs erstelle, was wird dann diese Relationstabelle? Da es IDDocument und IDUser hatte, aber jetzt würde ich ID nur von der Elternklasse haben –

Antwort

3

... hat mehrere Server DBs, in denen die Tabellen haben keine Beziehungen untereinander ...

Aber sie tun, um eine Beziehung haben, eine Many-to-Many Beziehung, die über das definiert ist dritte Zuordnungstabelle (ob das ein richtig definierte Beziehung ist ein anderes Thema)

... das Problem ist der generische Typ T keinen Sinn macht, und ich kann nicht Auswirkungen auf Werte in meinem Modell mit EF-Abfragen ...

Warum nicht und warum können Sie nicht? Ihre Tabelle Beispiele erwägen, würden Sie zwei Entitäten haben, User und Document und sie wie folgt aussehen würde:

public class User 
{ 
    public int IDUser { get; set; } 

    public virtual ICollection<Document> Documents { get; set; } 

    ... 
} 

public class Document 
{ 
    public int IDDocument { get; set; } 

    public virtual ICollection<User> Users { get; set; } 

    ... 
} 

Und Sie können in die fließend API verwenden, um Ihren Kontext OnModelCreating die Beziehung über die dritte Tabelle einrichten :

public class YourContext: DbContext 
{ 
    ... 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<User>() 
      .HasMany<Document>(u => u.Documents) 
      .WithMany(d => d.Users) 
      .Map(userJointDocument => 
       { 
        userJointDocument.MapLeftKey("IDUser"); 
        userJointDocument.MapRightKey("IDDocument"); 
        userJointDocument.ToTable("User_joint_Document"); 
       }); 
    } 

    ... 
} 

und dann können Sie User s und Document s in Ihrem Repository als würden Sie, wenn es eine direkte Beziehung zwischen ihnen war abfragen. Here sind more gut sources um mehr darüber zu erfahren, wenn Sie möchten.

+0

Danke für diese präzise Antwort und gute Dokumentation. Ich habe dies getan, aber ich bekomme immer noch Probleme in meinem Repo, ich kann die IDs nicht erkennen. Ich habe meine Frage bearbeitet, um zu zeigen, wie mein Repo aussieht –

+0

Kann dich nicht merkwürdig markieren –

1

Soweit ich Ihr Problem sehen kann, gibt es jetzt Art und Weise, dies zu erreichen, ohne zumindest eine Basisklasse oder eine Schnittstelle zu Ihren Einheiten/POCOs setzt

Sie mit Ausdrücken für das Erreichen ein generisches Repository rumspielen können

public interface IEntity<T> where T : class 
{ 
    Expression<Func<T, bool>> GetByIdPredicate(long id); 
}   

public partial class User : IEntity<User> 
{ 
    public int UserID { get; set; } 

    public Expression<Func<User, bool>> GetByIdPredicate(long id) 
    { 
     return (User entity) => entity.UserID == id; 
    } 
} 

class Repository<T>:IRepository<T> where T : class, IEntity, new() 
{ 
    private readonly ApplicationContext context; 
    private DbSet<T> entities; 
    T dummyEntity; 

    public Repository(PrincipalServerContext context) 
    { 
     this.context = context; 
     entities = context.Set<T>(); 
     dummyEntity = new T(); 
    } 
    public T Get(long id) 
    { 
    return entities.SingleOrDefault(dummyEntity.GetByIdPredicate(id)); 
    } 

Es ist wahrscheinlich ein sauberer Weg, die

des dummyEntity Feld wird auch loswerden
+0

Oh, das ist eine ziemlich interessante Einstellung. Ich habe meine Frage neu formuliert und hatte hier eine andere Antwort. Wenn Sie interessiert sind, wird alles in einer Methode mit den Expression-Methoden gepackt: https://stackoverflow.com/questions/44591796/does-a-generic-repository- need-a-base-entity-class-zu-angewandt-überall/44592318 # 44592318 –

Verwandte Themen