2013-04-07 72 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