使用流畅的NHibernate映射垂直传统表

时间:2010-12-08 22:18:49

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

我正在尝试映射下面的表设置,其中我无法控制(抱歉文本表,我无法发布图像):

**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问题相当棘手。有什么建议吗?

感谢您的任何意见。

1 个答案:

答案 0 :(得分:1)

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

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

我建议您不要尝试使用nHibernate直接映射到ProteinSample,而是建议您创建(自动生成最好)类,这些类镜像模式表(也称为DTO),然后在DTO之间手动映射(例如{{您MetadataDto中的1}},MetadataDictDtoSamplesDto)和您的域名实体(ProteinSample)。

我认为这会让问题更容易管理。