将业务层添加到ADO .NET实体框架

7
我正在进行我的第一个.NET项目(.NET 3.5,ADO.NET和C#)。我们已经构建了实体模型,并尝试构建一个清晰的业务对象层。
我们有基本的实体模型,并希望在默认数据访问器(导航属性等)中添加某些业务级语义。
例如,假设我们在Person和BankAccounts之间有一对多关系。在业务层面上,我们想要添加冻结账户的功能。现在,我们希望能够从Person导航到:
- 所有他们的银行账户, - 他们未被冻结的银行账户,以及 - 他们被冻结的银行账户。
自然地,我们希望将名义案例作为默认值:如果我导航到Person.BankAccounts(),我希望它返回他们未被冻结的账户。我可以添加导航属性Person.FrozenBankAccounts()和Person.AllBankAccounts()。
我们提出的两种方法似乎都有相当多的代码气味。
  1. 我们找不到覆盖实体模型方法的方法。 因此,将 Person.BankAccounts() 作为返回所有银行账户的访问器。 然后我们添加一个 Person.FrozenBankAccounts() 和一个 Person.NonFrozenBankAccounts()
  2. 向代码库添加另一个显式层,该层包装了对 BankAccounts 的所有访问。

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

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

是否有比我们考虑过的两种方法更好的方法? 如果没有更好的方法,我概述的这两种方法中哪一种似乎是更好的解决方案(考虑到我们需要处理50多个类)?

注意: 在进行网络搜索时,我发现了一封给微软的公开信,标题为ADO .NET Entity Framework Vote of No Confidence,似乎暗示着没有一个好的方法来实现清晰的关注点分离。

4个回答

4
我没有使用LINQ to Entities的经验,但是你的问题让我想起了我的上一个项目中遇到的类似问题。在那个项目中,我使用了另一个ORM,遇到了与你相似的问题。我定义了接口,而不是让业务对象层的客户端直接使用ORM生成的类或者复制所有类并实现大量的转发函数。业务对象层的客户端只会看到这些接口,而你的Entity类将实现这些接口,具有以下优点:
  • 在简单的情况下(没有业务逻辑),接口的开发成本很小。对于大多数成员,您不需要实现转发函数,只需从接口派生实体类即可
  • 在你提到的情况下,你可以在接口中添加BankAccounts属性,并通过显式接口实现让它转发到实现实体的NonFrozenBankAccounts。当然,你也可以添加任何你想要的检查
  • 作为额外的好处,你可以轻松地交换底层持久性层,而客户端代码不会有任何可见的变化

1
你可以添加两个新的实体类型,它们都继承自Account
- RegularAccount和FrozenAccount
并将你的IsFrozen字段作为继承条件添加(表层次结构)。
然后,你可以删除从“Person”到“Account”的关联,并创建两个新的关联:
从Person到RegularAccount,人员上的名称导航属性为“Accounts”。
从Person到FrozenAccount,人员上的名称导航属性为“FrozenAccounts”。

0

实现这个的一种方法如下:

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

希望这能帮到您。


-3
放弃EF,转而使用NHibernate
NHibernate的方式是:您创建业务对象,并告诉NHibernate如何将这些业务对象保存到数据库中。业务对象本身不知道它们如何被保存或加载,或者正在使用NHibernate。这被称为“持久性无知”。此外,您可以告诉NHibernate以几乎任何您喜欢的方式保存和加载业务对象。它对您描述的场景有很好的支持。
停止编写数据访问层并停止生成代码。使用真正男人的ORM

好的方法,不过它也可以用EF4实现。 - Danny Varod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接