2013-04-07 13 views
5

Il mio modello di dominio fornisce ad es. seguente oggetto Report : IEntity<Report>. Solitamente recupero l'oggetto tipo definito dall'utente Oracle (oi tipi di raccolta) dalle stored procedure. Per tutti i tipi, le classi C# vengono generate dalla Procedura guidata classe personalizzata di Visual Studio ODP.NET. Quindi ho la seguente classe:Come integrare ODP.NET nelle classi del repository?

public class UDT_REPORT : INullable, IOracleCustomType, IXmlSerializable { 
    private bool m_IsNull; 
    private decimal m_REPORT_ID; 
    private decimal m_VALUE;     
    // etc 
} 

Attualmente sto cercando di creare un nuovo livello di accesso ai dati per un'applicazione C#. Vorrei applicare il modello di repository in questo caso per ottenere un accoppiamento lento e una migliore testabilità. Ma come integrare queste classi generate in repository? Come progettare la classe ReportRepository?

public interface IReportRepository 
{   
    Report Find(ReportId id); 
    IList<Report> FindAll(); 
    void Store(Report Report); 
} 

Devo utilizzare il seguente approccio? Una classe proxy DB statico che, ad es. espone un metodo generico Read<T>() con un determinato delegato per il recupero e la mappatura dei dati. E una fabbrica per la creazione del provider db.

public static T Read<T>(string sql, Func<IDataReader, T> fetch, object[] parms = null) 
{ 
    using (var connection = factory.CreateConnection()) 
    { 
     connection.ConnectionString = connectionString; 

     using (var command = factory.CreateCommand()) 
     { 
      // Add connection; sql command text; 
        // add parameters via some extension method 
      // Open and close connection                   
      T t = default(T); 
      var reader = command.ExecuteReader(); 
      if (reader.Read()) { 
       t = fetch(reader); 
      } 
      return t; 
     } 
    } 
} 

E il seguente delegato viene utilizzato per il recupero del relativo oggetto UDT e il suo mapping sull'oggetto dominio, ad es. Report.

private static Func<IDataReader, Customer> Fetch = reader => 
{            
      UDT_REPORT report = reader.GetValue(reader.GetOrdinal("out_param_report")); 
      Report report = Mapping.Map(reportEntity);   
      return report; 
}; 

Cosa ne pensi di questo approccio? Esistono approcci migliori per l'integrazione dei tipi di ODP.NET nei repository? O dovrei evitare di generare classi UDT e aggiungere invece un frame ORM?

risposta

0

Quando ho adottato EF per la prima volta, ho utilizzato i repository Interfacce &, ma ho scoperto che hanno aggiunto un valore molto basso. Ecco un esempio di come appare ora il nostro stack.

Contesto:

Imports System.Configuration 
Imports System.Data.Entity 
Imports System.Collections.Specialized 

Imports Oracle.DataAccess.Client 
Imports System.Reflection 

Public Class MyContext 
    Inherits System.Data.Entity.DbContext 

    Public Property MyTables As DbSet(Of MyTable) 

    Public Sub New() 
     MyBase.New(
      New OracleConnection(
       ConfigurationManager.ConnectionStrings(
        "Entities").ConnectionString 
       ), 
      True 
     ) 
    End Sub 

End Class 

Esempio Entity:

Imports System.ComponentModel.DataAnnotations 
Imports System.ComponentModel.DataAnnotations.Schema 

Public Class MyTable 

    <Key()> 
    <Required()> 
    Public Property KeyColumn As Int64 

    <StringLength(50)> 
    <Column("LegacyColumnName")> 
    Public Property Name As String 

    <StringLength(1000)> 
    Public Property Description As String 

    <Required()> 
    Public Property IsActive As Int64 

    Public Property DateCreated As DateTime? 

End Class 

Esempio LINQ:

Public Function GetMyTables() 
    Try 
     Using MCTX As New MyContext() 
      Return (
       From T In MCTX.MyTables 
       Order By T.Name 
       Select New With { 
        T.KeyColumn, 
        T.Name, 
        T.IsActive 
       }).ToArray 
     End Using 
    Catch ex As Exception 
     Return ReportException(
      "An error occurred trying to retrieve the table list", ex) 
    End Try 
End Function 

Side-note, io non sono su re perché vorresti scrivere i proc per fare il recupero. Non è questo tipo di sconfiggere lo scopo di usare EF? Lo fa per te.

+0

Grazie per avermi fornito alcune informazioni sull'implementazione dell'accesso ai dati. Attualmente non sto usando EF. Le mie classi Entity sono classi C# generate da Oracle Developer Tools per Visual Studio (Custom Class Wizard). Devo fare affidamento sulle stored procedure come interfaccia (politica di sicurezza). Le procedure memorizzate e EF potrebbero funzionare con i cusori di riferimento come parametri di output. I campi del cursore possono essere mappati alle entità. Non c'è modo di mappare oggetti Oracle UDT in entità EF. –

+0

Cercherò di evidenziare alcuni fatti sulla situazione attuale: - Sono richieste procedure memorizzate (nessun parametro/sql dinamico). - La maggior parte delle procedure restituisce oggetti ([oggetti UDT Oracle] [1]) - Le classi C# generate da Oracle Visual Studio Tools vengono utilizzate come classi di entità. - Attualmente non viene utilizzato alcun ORM (nessun EF/nessun nibernetico). [1] http://docs.oracle.com/html/E10927_01/featUDTs.htm E vorrei migliorare la progettazione del codice di accesso ai dati. –