【问题标题】:refactoring: swicthing from custom data access layer to Entity Framework重构:从自定义数据访问层切换到实体框架
【发布时间】:2011-09-23 07:22:58
【问题描述】:

我是一名 .NET 开发人员,作为重构项目的一部分,我有几个问题。

我们的软件目前使用 Active Record 模式(数据对象和业务对象之间的一对一映射)。不好的是业务对象继承自数据对象,导致层间高度耦合。

我们的目标是从我们的自定义数据访问层(基于 ADO.NET)切换到实体框架。我们的限制是不要破坏代码,以便我们的旧应用程序仍然可以使用旧数据访问层编译和运行,同时允许我们将 EF 用于新项目。

我这样做的第一个想法是打破继承并将数据对象作为业务对象的属性(并使用接口或抽象类来注入数据对象,无论是我们的自定义层还是实体框架)。属性将从数据对象迁移到业务对象,业务对象就像某种“代理”来访问数据对象的属性。

这是一个可行的解决方案吗?那仍然会使用活动记录模式(我不太喜欢这个,因为我们的业务层已经变得很大了)所以如果您有任何其他想法,请不要犹豫。

我的另一个问题是关于实体框架的生成。我们需要实体属性与旧数据对象同名(我们将使用抽象类以允许业务对象调用数据对象的属性,无论是我们的自定义数据对象还是 EF 实体) .实现这一目标的最佳方法是什么?使用 T4 生成实体还是采用 EF 代码优先方法?

我对任何建议都持开放态度,因此请不要犹豫提出其他方法。感谢您的宝贵时间。

【问题讨论】:

    标签: .net entity-framework activerecord migration


    【解决方案1】:

    这会是一个可行的解决方案吗? 如果您要使用 Entity Framework 开始一个新项目,我会说:不。因为 Entity Framework 是 RepositoryUnit Of Work 模式和 Active Record 模式是完全不同的方法。

    即使您使用非 POCO、EntityObject 派生实体和实体框架,实体也不会成为真正的活动记录,因为 EntityObjectEntityCollection 公开的持久性功能是有限的(我相信是设计使然) . EntityObject 仅支持更改跟踪,EntityCollection 具有 LoadCreateSourceQuery 之类的功能,支持对该特定集合的查询。但是您手头没有完整的ObjectContext 来发出任意查询、删除对象或保存更改。

    EF 4.1 和DbContext 甚至不再支持此功能,因为EntityObject 派生实体不允许使用DbContext。这是一种纯粹的 POCO 方法,具有不知道持久性的实体。只有延迟加载和更改跟踪代理知道上下文,但这只是运行时的“透明”功能,您不能针对此代理上下文进行编程。

    现在,您不是从一个新项目开始,而是拥有一个您必须在很大程度上尊重的架构。如果您的数据对象基类(实现 Active Record)具有 LoadMeSaveMeLoadCustomersContacts 等方法,并且您在业务/服务层中使用这些方法并且您不能或不想更改这一层,那么您可能必须找到一个使用 Entity Framework 的有效 Active Record 方法。

    这是一种非标准方法,有点违反实体框架的架构。它提出了一些问题,例如:您如何管理与对象生命周期相关的上下文创建和生命周期?您如何处理事务性和非事务性行为? (SaveChanges 本身就是一个事务,您不能保存单个“行”或实体,您始终完全保存上下文/工作单元中的内容 - 修改、添加或删除。这可能不是您的 Active Record 方法的行为与 ADO.NET 有今天。)

    具体怎么做?我不知道,我从来没有使用过这种方法。尝试谷歌搜索“实体框架和活动记录模式”或其他内容,也许你会发现一些没有说“不要那样做!”。

    对于您的另一个问题:我更喜欢 DbContext 和 Code-First,以便于开发(这就是它的目的)。但请注意,有一些功能在 Code-First 中不受支持,需要基于 EDMX 的解决方案(我相信“模型定义的功能”就是其中之一)。 DbContext 还不支持映射到存储过程。您可以通过上下文发出原始 SQL 语句,但这可以解决此限制。

    这是我的看法。


    顺便说一句:欢迎使用 Stackoverflow!您的问题对于本网站的格式是有问题的,因为太笼统并且有点要求“意见”。我建议您将问题分解成更小的部分,并创建单独的更小和更具体的问题,也许用少量代码 sn-ps 装饰,使其更具体和有形。您通常会得到更多对此类问题的回应(并且比我上面的 blabla 更有价值的回应)。好消息是:您可以创建任意数量的问题。

    【讨论】:

    • 感谢您的回复,这与我想的一样。我认为我们将只对现有应用程序使用旧的数据访问层,并为新应用程序使用带有 DDD 方法的实体框架(并通过这样做来清理我们的代码和架构)。如果我们真的需要,也许我们会尝试在我们的活动记录实现中潜入 LinqToSQL(应该稍微优化性能),但这不是现在的优先事项。顺便说一句,感谢您的“BTW”建议。
    猜你喜欢
    • 2011-11-14
    • 2011-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多