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

时间:2009-01-11 14:39:49

标签: .net entity-framework .net-3.5 orm ado.net-entity-data-model

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

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

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

  • 所有银行帐户,
  • 他们的非冻结银行账户,
  • 他们冻结的银行账户。

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

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

  1. 我们找不到覆盖实体模型方法的方法。因此,请Person.BankAccounts()作为返回所有银行帐户的访问者。然后我们添加Person.FrozenBankAccounts()Person.NonFrozenBankAccounts()
  2. 将另一个显式图层添加到包含对BankAccounts
  3. 的所有访问的代码库中

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

    使用方法2,当我们从实体模型层继承对象时,我们必须覆盖每个方法以确保它不会从底层返回对象。因此,我们创建一个BL_Person,其中BankAccounts()方法返回BL_BankAccount个对象的集合。但在这种情况下,所有代码似乎都有些愚蠢。

    有没有比我们考虑过的更好的方法?如果没有更好的方法,我所概述的两个中哪一个似乎是更好的解决方案(假设我们需要使用50多个课程)?

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

4 个答案:

答案 0 :(得分:4)

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

  • 在直接的情况下(没有业务逻辑),接口的开发开销很小。对于大多数成员,您不需要实现转发功能,只需从界面“派生”实体类并使用它完成
  • 在您提及的情况下,您可以在界面中拥有属性BankAccounts,并通过显式接口实现将其转发到实现实体的NonFrozenBankAccounts。您当然也可以添加任何类型的支票
  • 作为一个额外的好处,您可以轻松地交换底层持久层,而无需为客户端代码明显更改任何内容

答案 1 :(得分:1)

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

然后,您可以删除从“人员”到“帐户”的关联,并创建两个新关联:

来自RegularAccount的人,在人员“帐户”上命名导航属性。

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

答案 2 :(得分:0)

这样做的一种方法是:

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

答案 3 :(得分:-3)

弃用EF而赞成NHibernate

NHibernate方式是:您创建业务对象,并告诉NHibernate如何将这些业务对象保存到数据库中。业务对象本身具有 no 知道如何保存或加载,或者正在使用NHibernate。这被称为“持久性无知”。此外,您可以告诉NHibernate几乎以您喜欢的方式保存和加载业务对象。它对您描述的场景有很好的支持。

停止编写数据访问层并停止代码生成。使用real man's ORM