我们应用程序中的数据访问层将使用 Oracle 的 UDT 功能。我们只会将 UDT 对象传入和传出数据库。
目前,我们使用 ODP.NET 提供的函数生成自定义类(它创建了一个看起来非常可怕的类,我们真的不希望在我们的代码库中使用它)。
然后我们使用一个单独的映射类,将自定义类映射到我们的一个业务对象(并在保存时返回)。
我正在努力寻找更好的方法来做到这一点。
我想我会放弃生成的类,只写一个实现 IOracleCustomType 的映射类。From/ToCustomObject 方法然后会从我的 UDT 映射到我的业务对象。但是,当我尝试它时,这给我带来了问题 - 我收到错误“对象属性未映射到自定义类型成员”。看来,除了这两种方法外,我的映射类中还需要属性 - UDT 中的每个项目都有一个属性。
例如 - 一个工作流 UDT 包含三个项目 - 一个状态、创建时间和创建者。我的 UDT 又好又简单:
TYPE workflow_type AS OBJECT
(status VARCHAR2(8)
,created_by VARCHAR2(30)
,created_datetime DATE
);
正如我希望它最终出现的业务对象一样:
public class Workflow
{
/// <summary>
/// Gets the status of the workflow.
/// </summary>
/// <value>The status.</value>
public string Status { get; private set; }
/// <summary>
/// Gets the Windows Logon Id of the user performing the action
/// </summary>
public string CreatedBy{ get; private set; }
/// <summary>
/// Gets the time of the action
/// </summary>
public DateTime CreatedTime { get; private set; }
}
我想从一个到另一个,而不必将 Oracle 代码添加到业务对象。
所以我的想法是创建一个这样的映射类:
public class WorkFlowMapper : IOracleCustomType
{
public BusinessObjects.WorkFlow BusinessObject {get; private set;}
public WorkFlowMapper(BusinessObjects.WorkFlow businessObject)
{
BusinessObject = businessObject;
}
public WorkFlowMapper(){}
public void FromCustomObject(OracleConnection con, IntPtr pUdt)
{
OracleUdt.SetValue(con, pUdt, "STATUS", BusinessObject.Status);
OracleUdt.SetValue(con, pUdt, "CREATED_BY", BusinessObject.CreatedBy);
OracleUdt.SetValue(con, pUdt, "CREATED_DATETIME", BusinessObject.CreatedTime);
}
public void ToCustomObject(OracleConnection con, IntPtr pUdt)
{
BusinessObject = new BusinessObjects.WorkFlow(
(string)OracleUdt.GetValue(con, pUdt, "STATUS"),
(string)OracleUdt.GetValue(con, pUdt, "CREATED_BY"),
(string)OracleUdt.GetValue(con, pUdt, "CREATED_DATETIME")
);
}
}
// Factory to create an object for the above class
[OracleCustomTypeMappingAttribute("MYUSER.WORKFLOW_TYPE")]
public class CurrencyExposureFactory : IOracleCustomTypeFactory
{
public virtual IOracleCustomType CreateObject()
{
WorkFlowMapper obj = new WorkFlowMapper();
return obj;
}
}
但这不起作用,因为需要 OracleObjectMappingAttribute 来映射每个属性(如在 ODP.NET 生成的类中)。这看起来真的很愚蠢,因为我根本不会使用它们。事实上,我可以让我的映射类工作,只需添加三行:
[OracleObjectMappingAttribute("STATUS")] public string a;
[OracleObjectMappingAttribute("CREATED_BY")] public string b;
[OracleObjectMappingAttribute("CREATED_DATETIME")] public DateTime c;
肯定有比进行如此可怕的黑客攻击更好的方法吗?毕竟,这些变量根本不会被使用——ODP.NET 似乎只是需要它们来获取要映射到的类型——但我认为这可以通过不同的方式实现。想法?