具有多个后端/DI 时的 ORM 和 POCO - 架构?自动映射器?

Posted

技术标签:

【中文标题】具有多个后端/DI 时的 ORM 和 POCO - 架构?自动映射器?【英文标题】:ORMs and POCOs when having multiple Backends/DI - Architecture? AutoMapper? 【发布时间】:2009-07-13 14:03:04 【问题描述】:

好的,标题没有说太多,抱歉。本质上,这是一个关于可以有多个数据库后端的应用程序的架构问题(好吧,“数据库”在这里被广泛使用,因为它可以表示从 MSSQL 到 XML 文件到内存中的 IList 的任何内容),本质上涉及存储库模式。

我有一组 POCO,它们基本上只是用作数据传输对象 (DTO),因此除了携带数据之外什么都不做。不幸的是,我看到自己需要用属性来装饰它们,即与某些 ORM 一起使用,甚至与 XmlSerializer 一起使用。这意味着它们现在有点绑定到数据库层,在我看来不再是简单的 POCO。

据我所见,我现在必须复制这些 DTO 类,以便我拥有一个具有属性和我需要的任何内容的特定于数据库的类,以及通过我的应用程序通用的第二个版本。然后我的模型必须转换它们(这是可以使用 AutoMapper 之类的东西的地方)

它仍然“感觉很奇怪”,因为我实际上是在复制我所有的 DTO 类,但对象到对象映射器的存在似乎表明这完全没问题。此外,这似乎复制了 ADO.net 方法,而有一个通用部分(下至数据集)和一个特定于数据库的部分。

正确吗?还是有不同的方法?

【问题讨论】:

【参考方案1】:

需要添加用于给定ORM的属性的(有些有限的)情况下,可以编写一个在运行时添加这些东西的包装器。您可以将此类代码添加到 ORM 构造函数(根据需要继承 ORM 或 ORM 初始化类)或 ORM 初始化事件。

下面给出了一个使用反射标记三个属性的示例,但可以轻松修改它以将属性添加到类型或所有属性等。

 PropertyDescriptor[] properties = TypeDescriptor.GetProperties(this);
 //Add as necessary
 string[] propertiesToTagForORM =  "Name", "Category", "Description" ;

 foreach (string propname in propertiesToTagForORM)
        
            PropertyDescriptor prop = properties[propname];
            if (prop != null)
            
                AttributeCollection runtimeAttributes = prop.Attributes;
                // make a copy of the original attributes 
                // but make room for one extra attribute
                Attribute[] attrs = new Attribute[runtimeAttributes.Count + 1];
                runtimeAttributes.CopyTo(attrs, 0);
                attrs[runtimeAttributes.Count] = new BrowsableAttribute(false); 

                prop = TypeDescriptor.CreateProperty(this.GetType(), propname, prop.PropertyType, attrs);
                properties[propname] = prop;
            
        

改编自here。只是一个想法 - 这可能是我的第一个方向:)

【讨论】:

这是一个有趣的想法。本质上,我可以将后端作为单独的程序集,并让它们根据需要操纵 POCO……我肯定会记得这种方法。 确实如此。如果您尝试它,获得有关它如何为您工作的反馈会很有用。如果是这样,请在此处发布。【参考方案2】:

当您在 POCO 中包含这些属性时,您应该问问自己出了什么问题。特别是如果您的 POCO 只是携带数据并且不用作具有业务逻辑的域模型,那么您希望在属性中保持单独的“技术细节”形式。在那种情况下,这些属性的唯一缺点似乎是将较低级别的技术细节泄漏到较高级别。但这是否证明了一个全新的层是合理的,在这个层中你只做“愚蠢的属性复制”。我可能会说不是。

简而言之:始终仔细考虑对感知问题的解决方案是否不会导致其自身的另一个(甚至更大)问题。在您说明的情况下,我自己不会太担心这些属性。如果有的话,我宁愿寻找将属性排除在 POCO 之外并将它们放在其他资源(类或配置文件)中的选项,而不是引入额外的转换层。

【讨论】:

我只是认为,如果我有 3 或 4 组不同的元数据“集”,它们可能会很乱,这是我的担心。 我理解,但请仔细考虑混乱的实际程度,以及添加额外的转换和类是否只会让事情变得更加混乱和复杂。我见过太多不经意地求助于 DTO 的项目,事后看来,这并没有增加任何价值,但确实产生了巨大的维护开销。在这些情况下,我真的很想打电话给 YAGNI,直到证明不是这样。

以上是关于具有多个后端/DI 时的 ORM 和 POCO - 架构?自动映射器?的主要内容,如果未能解决你的问题,请参考以下文章

延迟初始化、ORM 和 lambda

Spring事务管理--多个ORM框架在使用时的情况分析

具有 1000 多个表的数据库的 ORM

具有共享数据库的微服务?使用多个 ORM? [关闭]

具有多个选项的相同键的 django orm AND 条件

在具有相同架构的多个数据库中使用 EF(或另一个 .NET ORM)