【问题标题】:Mapping Vertical Legacy Table with Fluent NHibernate使用 Fluent NHibernate 映射垂直遗留表
【发布时间】:2011-05-22 12:47:23
【问题描述】:

我正在尝试映射以下表格设置,我无法控制(对不起,文本表格,我还不能发布图片):

**METADATA**
METADATA_ID NUMBER(10,0)
METADATA_DICT_ID    NUMBER(10,0)
SAMPLE_ID   NUMBER(10,0)
CREATED_BY  NUMBER(10,0)
CREATE_DATE DATE
REQUIRED    VARCHAR2(9 BYTE)
METADATA_VALUE  VARCHAR2(300 BYTE)
METADATA_LARGE_VALUE    CLOB

**METADATA_DICT**
METADATA_DICT_ID    NUMBER(10,0)
METADATA_DICT_TYPE_ID   NUMBER(10,0)
METADATA_DICT_NM    VARCHAR2(60 BYTE)
DESCRIPTION VARCHAR2(512 BYTE)
CREATE_DATE DATE
CREATED_BY  VARCHAR2(20 BYTE)


**SAMPLES**
METADATA_DICT_ID    NUMBER(10,0)
METADATA_DICT_TYPE_ID   NUMBER(10,0)
METADATA_DICT_NM    VARCHAR2(60 BYTE)
DESCRIPTION VARCHAR2(512 BYTE)
CREATE_DATE DATE
CREATED_BY  VARCHAR2(20 BYTE)

基本上,一个样本有一个元数据属性的集合,每个属性都是一个键/值对(有点问题,因为值可以在 CLOB 列或 varchar2 列中,具体取决于其大小)。每个键/值对的键对应于正在收集的信息类型(METADATA_DICT_ID),而键对应于用户提供的值(METADATA_VALUE / METADATA_LARGE_VALUE)。例如,可能会提示用户输入“质粒类型”,他们会回答“源克隆”。这样做的原因是用户可以通过定义新的元数据类型来动态添加新类型的信息(问题)以收集有关样本的信息。这实际上非常适合他们的目的,但我现在想创建一个域模型以在 ASP.NET MVC 应用程序中使用,并且我想用 NHibernate 填充该域模型。

似乎有几种方法可以解决这个问题。最终,我想要以下结构的数据:

public class ProteinSample : PersistentObject
    {
        public virtual SampleType SampleType { get; set; }
        public virtual Project Project { get; set; }
        public virtual long Variant { get; set; }
        public virtual DateTime CreationDate { get; set; }
        public virtual User User { get; set; }

        //Metadata table values:
        public virtual string PrepNumber { get; set; }
        public virtual string Host { get; set; }
        public virtual string NTermTag { get; set; }
        public virtual string CTermTag { get; set; }
        public virtual string Buffer { get; set; }
        public virtual double ConcentrationMgPerMl { get; set; }
        public virtual double StorageTemperatureCelsius { get; set; }
        public virtual string PurificationProtocol { get; set; }
        public virtual string Comments { get; set; }
        public virtual string ProteinSequence { get; set; }
    }

如果我可以让 NHibernate 将键值对元数据表中的数据直接放入上述每个属性(PrepNumber、Host、NTermTag 等),那将是理想的。目前我所拥有的如下:

 public class ProteinSample : PersistentObject
        {

            public virtual SampleType SampleType { get; set; }
            public virtual Project Project { get; set; }
            public virtual long Variant { get; set; }
            public virtual DateTime CreationDate { get; set; }
            public virtual User User { get; set; }

            public virtual IList<SampleMetadata> Metadata { get; set; }
        }  

public class SampleMetadata : PersistentObject
    {
        public virtual ProteinSample ProteinSample { get; set; }
        public virtual MetadataType MetadataType { get; set; }
        public virtual string Value { get; set; }
        public virtual string LargeValue { get; set; }
    }

public class MetadataType : PersistentObject
    {
        public virtual string MetadataDictionaryName { get; set; }
    }

这是有效的,但我希望将 List 展平为上面第一类中的特定 I 属性。如果人们想查看它们,我可以提供我的 Fluent NHibernate 映射。

这可能是我提取数据后 AutoMapper 的工作吗?

人们怎么看?

METADATA_LARGE_VALUE 与 METADATA_VALUE 的互斥问题非常棘手。有什么建议吗?

感谢您的任何意见。

【问题讨论】:

    标签: orm fluent-nhibernate nhibernate-mapping mapping automapper


    【解决方案1】:

    我在这里看到的关键是Separation of Concerns

    您的域对象还包含有关它如何持久化的知识(因为它继承自 PersistableObject),这对 IMO 一个对象来说责任太大了。持久性和业务逻辑是不同的问题。

    与其尝试直接使用 nHibernate 映射到 ProteinSample,我建议您创建(最好是自动生成)镜像模式表(也称为 DTO)的类,然后在 DTO 之间手动映射(例如 MetadataDtoMetadataDictDtoSamplesDto) 和您的域实体 (ProteinSample) 在您的 ProteinSampleRepository 中。

    我认为这将使问题更易于管理。

    【讨论】:

    • 感谢您的回复 - 您是否推荐任何特定的逆向工程/自动生成工具?
    • 其实我只想说我找到了这个帖子:stackoverflow.com/questions/2604362/…,它引用了这个ThoughtWorks映射工具:codeplex.com/Wikipage?ProjectName=nmg;乍一看,这真是太棒了。我刚刚在大约 2 分钟内对数据库进行了逆向工程 - 我即将对其进行测试......
    • 我真的很喜欢使用 CodeSmith,但它需要花钱。如果这不是一个选项,您应该能够使用 ADO.NET 查询 oracle 模式元数据并通过组装字符串自己生成文件。
    • 关注点分离并不是真正的问题。此外,NHibnernate 的全部意义在于避免代码直接了解特定的持久性机制和用法(我说的是表/列名称和模式,而不是使用 NHibernate 的事实)。即使使用 DTO,您也不希望它们是特定于模式的。如果遗留表变成更有用的东西会怎样?
    • @Rich 然后您重新生成 DTO 并更改将 DTO 映射到业务对象的代码,而您的业务对象保持不变,因为持久性已更改,但域模型未更改。
    猜你喜欢
    • 2010-12-25
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 2011-06-18
    • 2010-12-09
    • 2012-04-03
    相关资源
    最近更新 更多