使用 Fluent NHibernate 映射垂直旧表

发布于 2024-10-06 17:06:39 字数 3220 浏览 4 评论 0原文

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

**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; }
    }

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

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

人们怎么看?

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

感谢您的任何意见。

I am trying to map the following table setup, of which I have no control over (sorry for the text tables, I can't post images yet):

**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)

Basically, a sample has a collection of metadata attributes, each of which is a key / value pair (with a little gotcha, in that the value can be in either a CLOB column, or a varchar2 column, depending on its size). Each key / value pair's key corresponds to a type of information being collected (METADATA_DICT_ID), while the key corresponds to a value the user has supplied (METADATA_VALUE / METADATA_LARGE_VALUE). A user might be prompted for 'Plasmid Type', and they would answer 'Source Clone', for instance. The reason for doing this was so a user can dynamically add new types of information (questions) to collect about samples by defining new metadata types. This actually works pretty well for their purposes, but I want to create a domain model now for use in an ASP.NET MVC app, and I want to populate that domain model with NHibernate.

It seems like there are a couple of ways to approach this. Ultimately, I want the data in the following structure:

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; }
    }

It would be ideal if I could get NHibernate to put data from the key-value pair Metadata table into each of above properties (PrepNumber, Host, NTermTag, etc...) directly. Currently what I have is the following:

 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; }
    }

which is working, but I want that List flattened out into the specific I properties in the first class above. I can supply my Fluent NHibernate mappings if folks want to see them.

Is this perhaps a job for AutoMapper after I pull the data out?

What do people think?

The mutually exclusive METADATA_LARGE_VALUE vs. METADATA_VALUE issue is pretty tricky. Any suggestions there?

Thanks for any input.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

相对绾红妆 2024-10-13 17:06:39

我在这里看到的关键是关注点分离

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

我建议您不要尝试直接使用 nHibernate 映射到 ProteinSample,而是创建(自动生成最好)镜像架构表(又名 DTO)的类,然后在 DTO 之间手动映射(例如 MetadataDtoMetadataDictDtoSamplesDto)和 ProteinSampleRepository 中的域实体 (ProteinSample)。

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

The key thing I see here is Separation of Concerns:

Your domain object also contains knowledge of how it's persisted (because it inherits from PersistableObject), and that's too much responsibility for one object IMO. Persistence and business logic are separate issues.

Instead of trying to map to ProteinSample directly using nHibernate, I'd recommend you create (autogenerate is best) classes that mirror the schema tables (aka DTOs) and then manually map between the DTOs (e.g. MetadataDto, MetadataDictDto, SamplesDto) and your domain entity (ProteinSample) in your ProteinSampleRepository.

I think that'll make the problem easier to manage.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文