我正在开发一个复合整体系统应用程序,不同的公司可能会添加不同的模块,但只有一个数据库。我的框架中有一个通用存储库,它是技术独立的(我的意思是它是提供者基础,现在默认提供者是 EF 4.1)。我已经分离了包含 poco 实体的公共层,并且每个模块在它们自己的程序集中也有不同的实体。现在的问题是实体映射。我无法从我的 EF 提供程序项目中访问我的实体,因为我不知道未来的模块!那么如何以通用方法映射我的实体?可能吗?
我认为一种解决方案是拥有一个配置文件并添加实体 FullName 然后迭代和反映每个实体,然后我可以将它们添加到 OnModelCreat(...) 方法中,但当然存在一些性能问题。
编辑:首先感谢您的回复 Ladislav。但是还有更多信息给你。
您可以要求每个模块必须包含它使用的每个新实体的映射类。当您启动应用程序时,您将只使用反射来获取从 StructuralTypeConfiguration<> 派生的所有类(包括实体和复杂类型),创建这些类型的实例并将它们添加到 DbModelBuilder 中的 Configurations 集合中(可以在 OnModelCreating 中完成)。
这将需要一些时间,但它只会在第一次使用上下文时发生一次。您可以在应用程序启动期间触发此创建 - 应用程序只需要一些时间来启动和配置它们需要使用的所有基础设施。
编辑:
我必须在每个不适合这种情况的模块中引用 EntityFramework.dll。
是的。您希望允许其他开发人员定义他们自己的实体,这些实体将由您的核心应用程序持久化。在这种情况下,他们必须使用您选择的持久性框架来告诉您的应用程序如何持久化他们的实体。
==>正如我之前提到的,EF 不是我唯一的 DataProvider !我必须有一些其他的 DP,例如 DB4O 的数据提供者等,所以我不想引用每个提供者对每个模块的依赖项......因此我需要将 EF 封装在一个单独的程序集中
如果您使用存储库,每个模块甚至应该包含自己的存储库以使用其自己的实体 - 通用存储库不存在。通用存储库是多余的无用层,只会使您选择的 ORM 的工作更加困难。说清楚 - 存储库模式的正确实现不是通用的。它是特定的,它公开了单个实体或聚合根的数据访问功能。
==>我可以要求任何可靠的参考吗?!为什么我应该为每个模块添加一个存储库,以防只有一个存储库可以满足我的所有要求?哪个是多余的?在我看来,使用特定或通用代表在正确的情况下都是正确的。我的模块中有 90% 具有来自存储库的相同要求,并且它们都应该具有 CRUD ...
如果您不希望模块中的 EF 依赖,要么根本不使用 EF,要么定义您自己的中间映射层,该层将在您的应用程序中转换为特定映射 - 大量工作零附加值。
==>事实上,我正在尝试定义自己的映射层,因为我在我的应用程序架构中需要它。它对我来说不是没用的。这是我问如何实现它的唯一原因。我正在寻找最好的解决方案,我希望你能帮我解决它:)
其他选项就是不允许您的模块使用新实体,因为它看起来更像您当前的期望。如果模块开发人员必须为他的实体定义新的数据库表,他还必须能够使用持久性并定义表和他的实体之间的映射。
==>好主意,但不适合我的情况;)
我必须在启动时反映每个模块 dll,这意味着要反映很多沉重的 dll 并且......还有其他想法吗?
您是否在启动过程中见过 Photoshop、Visual Studio 甚至 MS Office 应用程序等应用程序?当您看到启动画面时,您认为发生了什么?应用程序正在初始化 - 它正在加载和初始化其功能和插件。即使是服务器应用程序也可能需要几分钟才能完全启动。您正在构建模块化应用程序(不是复合应用程序),因此您必须为该要求付费。
==>是的,我想我看到了其中一些!例如,如果他们在启动时加载所有托盘或侧边栏,他们必须雇用我。嘿亲爱的微软,如果您不知道什么是延迟加载,我可以帮助您提高性能 :)
如果您不想自己使用反射,可以使用 MEF 构建模块化基础架构。
==>我已经在使用 Prism 和 MEF 来处理模块化,但仅适用于模块,不适用于我的提供商......
听起来 EF 不是企业复合应用程序的好解决方案,对吧?
您没有提出任何不应由 EF 满足的企业要求。您只是与您的期望作斗争,以允许模块开发人员使用新实体,但不让他们能够描述这些实体将如何被持久化——但谁来描述呢?
==>一个模型或一个中间映射器层,如果 EF 支持,它将在每个模块加载和映射实体(据我所知不能)我需要像引导程序这样的东西来为每个提供者映射实体:)
您不是在构建复合应用程序。复合应用程序采用单独工作的现有功能(组件、现有应用程序)并将它们组合到一个新应用程序中。您正在构建模块化应用程序,您的核心可以托管其他模块,但如果没有您的托管基础设施,这些模块将无法运行。
==>我不打算就我的应用程序及其架构进行演讲,但我认为就这么多就足够了,你知道这是一个复合/模块化应用程序......
我应该切换到模型优先吗?!!
模型优先(通常是 EDMX)确实不适合您的期望,因为在模型优先的情况下,每个模块都需要自己的 EDMX 文件和自己的上下文。
==>但我可以在运行时更改 EDMX 文件的模型和 xml,对吗?!
您也不能首先通过代码使用自动数据库生成,因为任何新模块都会破坏您的应用程序或 EF 将删除您当前的数据库。
==>感谢这个建议,虽然我以前知道,但我当然会更加关注它。