我们应用程序中的数据访问层将使用Oracle的UDT功能。我们只会向数据库传递UDT对象。
目前,我们使用ODP.NET提供的函数来生成自定义类(它会创建一个非常难看的类,我们不想在代码库中使用)。
然后,我们使用单独的映射类将自定义类映射到我们的业务对象之一(并在保存时进行反向映射)。
我正在试图找到更好的方法来做这件事。
我认为我可以放弃生成的类,只编写一个实现IOracleCustomType的映射类。 From/ToCustomObject 方法将从我的UDT映射到我的业务对象。 然而,当我尝试这样做时遇到了问题——我得到了错误消息“对象属性未映射到自定义类型成员”。 似乎除了这两个方法之外,我的映射类还需要属性——UDT中每个项需要一个属性。
例如-工作流UDT包含三个项-状态、创建时间和创建者。 我的UDT很简单:
我希望能够在不增加Oracle代码到业务对象的情况下完成从一个对象到另一个对象的转换。
因此,我的想法是创建一个类似这样的映射类:
```` // 代码示例 ````
但是由于需要为每个要映射的属性添加OracleObjectMappingAttribute(在ODP.NET生成的类中),所以这种方法行不通。这看起来非常愚蠢,因为我根本就不会使用它们。事实上,只需添加三行代码即可使我的映射类正常工作:
目前,我们使用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;
肯定有比使用这样可怕的hack更好的方法吧?毕竟,这些变量根本没有被使用 - ODP.NET似乎只需要它们来获取映射类型 - 但我认为可以用不同的方式实现这一点。你有什么想法吗?