【问题标题】:Entity Framework, repository and Linq? Load just an entity or also child nodes?实体框架、存储库和 Linq?只加载一个实体还是子节点?
【发布时间】:2012-08-08 01:23:26
【问题描述】:

我是 Entity Framework 的新手,我想了解一些关于 EF、LINQ、POCO 和存储库的观点。

我们有一个有效的解决方案,其中包含一个使用 EF 和 POCO 访问数据库的存储库。我们通过上下文在 LINQ 中进行所有查询。我们将映射添加到映射类中,这些映射类在应用程序启动时加载,因为数据库/表已经存在。

如果我有一个商业案例,我需要为特定公司计算员工为孩子购买的玩具数量。

我将如何构建存储库?

A:用一个存储库调用公司的所有员工,然后在服务层再次为每个员工的孩子调用另一个存储库,等等?

B:调用一个存储库,它会将公司连同所有员工、孩子和玩具归还给我?

在我看来,A 看起来更干净,我可以更频繁地重用存储库。但是 B 接缝更有效,但不能重复使用。更少的存储库和查询会变得越来越大。

这只是一个小例子……但我们有更大的业务案例。在这种情况下,最好的架构方法是什么?

class Company
{
    List<Employee> employees;
}

class Employee
{
    List<Child> children;
}

class Child
{
    List<Toy> toys;
}

【问题讨论】:

  • 为什么需要存储库?你不能直接使用你的ORM吗?所有这些担忧都会立即消失。
  • 我们添加了 Repo 以将 DBaccess / ORM 与业务逻辑分开。
  • ORM已经分离了。
  • 是的,但是如果我们想从 EF 切换到 nHibernate 怎么办?
  • 你不会的。您的应用程序以许多微妙的方式依赖于 EF。你只是没有意识到。此外,您不需要同时使用它们。

标签: entity-framework architecture repository repository-pattern poco


【解决方案1】:

您无需调用存储库即可获取公司、员工、儿童和玩具!

我需要为特定公司计算员工为那里的孩子购买的玩具数量

因此,您的业务案例是有一个数字,或者每个玩具有一个数字或每个员工有一个数字。您不需要加载所有这些实体并在您的应用程序中计算它。您只需要编写一个聚合查询(在 Linq 或 SQL 中)。整个计算应该在数据库中运行。

如果您需要将查询隐藏在存储库后面,只需选择此业务案例所属的查询,并将查询公开为存储库的新方法。

【讨论】:

  • 这里的问题是聚合查询什么时候变成业务逻辑?如果我将它扩展为有一个玩具价格表并想计算成本。你还会使用聚合查询吗?对我来说,这听起来有点像在数据访问层做业务逻辑/计算。不是吗?
  • 查询是业务逻辑的一部分。在数据库中执行它并不重要 - 您在业务逻辑中定义它并使用它来实现逻辑。如果您按照最初描述的方式进行操作,您的应用程序在小型数据集上的性能会很差,而在大型数据集上将毫无用处。
  • 如果我问其他架构师,他们会告诉我查询不是业务逻辑的一部分,但业务逻辑需要查询来获取数据。一次加载所有需要的想法很好。我明白了!
  • 你会尝试使用 linq2SQL 进行所有可能的计算吗?你什么时候开始在服务中做逻辑?
  • 当它是需要.NET代码来计算的逻辑时。如果只是聚合查询,则没有理由收集应用程序中的所有数据来计算结果。
【解决方案2】:

虽然从来没有硬性规定,但对我来说,为每个聚合根(在您的示例中,Company)使用单个工作单元似乎最一致地工作以保持事物井井有条,并防止并发错误,因为它将处理所有的接线和管理您的对象。 a great MSDN 发布了关于什么是工作单元的帖子。该文章的摘录:

在某种程度上,您可以将工作单元视为一个倾倒所有内容的地方 事务处理代码。工作单位的职责 是:

  • 管理事务。
  • 排序数据库插入、删除和更新。
  • 防止重复更新。在工作单元对象的单一用法中,代码的不同部分可能会标记同一张发票
    对象已更改,但工作单元类只会发出一个
    向数据库发送单个 UPDATE 命令。

使用工作单元模式的价值在于释放你的其余部分 这些问题的代码,以便您可以专注于 业务逻辑。

有几篇关于此的博客文章,但我发现关于如何实现它的最好的一篇是here。还有一些其他的已经从这个网站herehere引用。

在我看来,A 更干净,我可以更多地重用存储库 经常。但是 B 接缝更有效,但不能重复使用。 存储库越少,查询就会越来越大。

通用存储库在此处处理您的问题,使您可以轻松地为每个数据对象创建一个存储库,同时使其可重用且易于测试。然后,您的业务逻辑可以在您的工作单元的服务层中处理,确保您没有并发问题。

【讨论】:

  • MSDN 帖子帮助我了解了我们已经在服务层中使用的工作单元的一些要点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多