如何将ODP.NET集成到Repository类中?

Mar*_*yer 5 c# oracle odp.net

我的域模型提供了例如以下对象Report : IEntity<Report>.我通常检索Oracle用户定义的类型对象(或集合类型)表单存储过程.对于所有类型,C#类由ODP.NET Visual Studio自定义类向导生成.所以我有以下课程,例如:

public class UDT_REPORT : INullable, IOracleCustomType, IXmlSerializable {
    private bool m_IsNull;
    private decimal m_REPORT_ID;
    private decimal m_VALUE;                
    // etc
}
Run Code Online (Sandbox Code Playgroud)

目前我正在尝试为C#应用程序创建一个新的数据访问层.我想在这种情况下应用存储库模式,以实现松耦合和更好的可测试性.但是如何将这些生成的类集成到存储库中?如何设计ReportRepository课程?

public interface IReportRepository
{         
    Report Find(ReportId id);
    IList<Report> FindAll();
    void Store(Report Report);
}
Run Code Online (Sandbox Code Playgroud)

我应该使用以下方法吗?静态数据库代理类,例如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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以下委托用于获取相关的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;
};
Run Code Online (Sandbox Code Playgroud)

您如何看待这种方法?是否有更好的方法在存储库中集成ODP.NET类型?或者我应该避免生成UDT类并添加一些ORM帧吗?

Tom*_*day 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
Run Code Online (Sandbox Code Playgroud)

示例实体:

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
Run Code Online (Sandbox Code Playgroud)

示例 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
Run Code Online (Sandbox Code Playgroud)

旁注,我不确定您为什么要编写过程来进行检索。这不是违背了使用EF的目的吗?它为你做到这一点。