2013-04-07 40 views
5

我的域模型提供了例如以下對象Report : IEntity<Report>。 我通常檢索Oracle用戶定義的類型對象(或集合類型)表單存儲過程。對於所有類型,C#類都由ODP.NET Visual Studio自定義類嚮導生成。所以我有以下課例如:如何將ODP.NET集成到Repository類中?

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

目前我正在嘗試爲C#應用程序創建一個新的數據訪問層。我想在這種情況下應用存儲庫模式,以實現鬆耦合和更好的可測試性。但是如何將這些生成的類集成到存儲庫中?如何設計ReportRepository課程?

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

我應該用下面的方法嗎? 靜態數據庫代理類,例如公開一個通用Read<T>()方法與給定的委託進行數據檢索和映射。還有一個創建數據庫提供程序的工廠。

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; 
     } 
    } 
} 

下面的委託用於獲取相關的UDT對象並將其映射到域對象,例如, 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; 
}; 

您對這種方法有什麼看法?在存儲庫中整合ODP.NET類型有更好的方法嗎?或者我應該避免生成的UDT類並添加一些ORM框架?

回答

0

當我第一次採用EF時,我使用了接口&存儲庫,但是我發現它們增加的價值很小。這裏是我們的堆棧現在的樣子。

語境:

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 

樣品實體:

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 

樣品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 

側面說明,我不是蘇爲什麼你會想要編寫過程來做檢索。這種做法是否不符合使用EF的目的?它爲你做到了。

+0

感謝您爲我提供一些有關數據訪問實施的信息。目前我沒有使用EF。我的實體類是由Oracle Developer Tools for Visual Studio(自定義類嚮導)生成的C#類。我必須依靠存儲過程作爲接口(安全策略)。存儲過程和EF可能與ref cusors一起作爲輸出參數。遊標的字段可以映射到實體。沒有辦法將Oracle UDT對象映射到EF實體。 – 2013-04-08 15:12:11

+0

我會嘗試關注當前情況的一些事實: - 需要存儲過程(不需要參數化/動態sql)。 - 大多數過程返回對象([Oracle UDT對象] [1]) - 由Oracle Visual Studio Tools生成的C#類用作實體類。 - 目前沒有使用ORM(沒有EF /沒有nhibernate)。 [1] http://docs.oracle.com/html/E10927_01/featUDTs.htm 我想改進數據訪問代碼的設計。 – 2013-04-08 15:41:09