7

我正在开发我的第一个 .NET 项目(.NET 3.5、ADO.NET 和 C#)。我们已经构建了我们的实体模型,并正在尝试构建一个干净的业务对象层。

我们已经有了基本的实体模型,并且我们希望将某些业务级语义添加到默认数据访问器(导航属性等)。

Person例如,假设我们在和之间存在多对多关系BankAccounts。假设我们想在业务层添加冻结帐户的功能。我们现在希望能够从 Person 导航到:

  • 他们所有的银行账户,
  • 他们未冻结的银行账户,以及
  • 他们冻结的银行账户。

自然,我们希望将名义情况设为默认值:如果我导航Person.BankAccounts(),我希望它返回他们未冻结的帐户。我可以添加导航属性Person.FrozenBankAccounts()Person.AllBankAccounts().

我们提出的两种方法似乎都有相当多的代码气味。

  1. 我们找不到覆盖实体模型方法的方法。Person.BankAccounts()因此,作为返回所有银行账户的访问者离开。然后我们添加 aPerson.FrozenBankAccounts()和 a Person.NonFrozenBankAccounts()
  2. 向代码库添加另一个显式层,该层包含对BankAccounts.

对于方法 1,问题在于名义业务案例(访问未冻结的银行账户)是该批次中最不直观的方法名称。

使用方法 2,当我们从实体模型层子类化对象时,我们必须重写每个方法以确保它不会从底层返回对象。所以我们创建了BL_Person一个BankAccounts()返回BL_BankAccount对象集合的方法。但在这种情况下,所有这些代码似乎有点傻。

有没有比我们考虑的两个更好的方法?如果没有更好的方法,我概述的两种方法中的哪一种似乎是更好的解决方案(鉴于我们需要使用 50 多个类)?

注意:在进行网络搜索时,我确实找到了一封致 Microsoft 的公开信,标题为ADO .NET Entity Framework Vote of No Confidence,这似乎暗示没有添加明确分离关注点的好方法。

4

4 回答 4

4

我没有使用 LINQ to Entities 的经验,但您的问题敲响了警钟。在我的上一个项目中,我在使用另一个 ORM 时遇到了几乎相同的问题。我没有让业务对象层的客户端直接使用 ORM 生成的类或复制所有类并实现大量转发功能,而是定义了接口。您的业​​务对象层的客户端只能看到这些接口,而您的实体类将实现这些接口,具有以下优点:

  • 在直接的情况下(没有业务逻辑),接口的开发开销是最小的。对于大多数成员,您不需要实现转发功能,只需从接口“派生”实体类并完成即可
  • 在您提到的情况下,您可以在接口中拥有一个属性 BankAccounts 并通过显式接口实现让它转发到实现实体的 NonFrozenBankAccounts 。你当然也可以添加任何你想要的支票
  • 作为一个额外的好处,您可以轻松地交换底层持久层,而无需明显更改客户端代码的任何内容
于 2009-01-11T15:39:57.957 回答
1

您可以添加两个从 Account 继承的新实体类型
- RegularAccount 和 FrozenAccount
,并将您的 IsFrozen 字段添加为继承条件(每个层次结构的表)。

然后您可以删除从“Person”到“Account”的关联并创建两个新关联:

Person to RegularAccount,在人“Accounts”上命名导航属性。

人到 FrozenAccount,在人“FrozenAccounts”上命名导航属性。

于 2011-04-12T07:10:31.597 回答
0

一种方法是这样的:

  1. 定义您的 AllBankAccounts 属性(甚至可能将其设为私有)。
  2. 在部分 Person 类中定义 BankAccounts 属性。该属性可以使用 LINQ 以 AllBankAccounts 的形式表示,即 AllBankAccounts.Where(a => !a.IsFrozen)
  3. 在部分 Person 类中定义 FrozenBankAccounts 属性,如步骤 2。

希望有帮助。

于 2009-02-20T04:30:08.987 回答
-3

抛弃 EF 转而使用NHibernate

NHibernate 的方式是:您创建业务对象,然后告诉 NHibernate 如何将这些业务对象保存到数据库中。业务对象本身知道它们是如何保存或加载的,也不知道 NHibernate 正在被使用。这叫做“执着无明”。另外,您可以告诉 NHibernate 以几乎任何您喜欢的方式保存和加载您的业务对象。它对您描述的场景有很好的支持。

停止编写数据访问层并停止生成代码。使用真人的 ORM

于 2009-01-11T14:58:05.080 回答