【问题标题】:What's the most efficient way to implement a simple ORM framework?实现简单 ORM 框架的最有效方法是什么?
【发布时间】:2015-09-15 00:23:51
【问题描述】:

我们有一个简单的数据库,但它可以包含数千行。我们正在尝试在它之上构建一个简单、轻量级的 ORM 层。想想Dapper。但是,我们正在努力弄清楚如何确保每个 ID 只存在一个对象。

考虑以下数据:

ID    Last       First
===== ========== =======
19    Donnely    Rick
20    Donovan    Sarah
21    Edwards    Sandra

现在考虑以下用于在 ORM 层中创建 Person 对象的 SQL。

Select * From People Where ID = 20;

Select * From People Where LastName Like 'Don*'

在第一种情况下,您会返回“Donovan”,但在第二种情况下,您会同时返回“Donovan”和“Donnely”。由于 Donovan 已经返回,我们希望该实例返回。

现在您当然需要通过 ID 进行一些查找。这很容易。不是查询数据库,返回行,然后确定在创建对象时需要创建新对象还是更新现有对象(以防数据更改)。

我唯一能想到的就是让查找有一个 GetObjectById 方法,它要么返回一个现有对象,要么创建一个新对象,存储它,然后返回它。我认为它还必须基于弱引用,这样它们就不会一直在内存中“徘徊”。

// Assume the implementation stores the references weakly
public Person GetPersonById(int id)
{
    Person person = this[id]; // assume this returns null if not found

    if(person == null)
    {
        person = new Person(id);
        this[id] = person;
    }

    return person;
}

...或者我做错了?

【问题讨论】:

  • 如果它是只读的,为什么要创建副本或仅仅返回原始文件?
  • 你是对的。我遗漏了相关信息。当我开始解释它时,我意识到这对这个问题来说是多余的,所以我删除了所有对只读的引用,以免让人们走错路。感谢您的提醒。
  • 在这种情况下,只要您正确使用弱引用,您的方法似乎与您将获得的一样好。另一种选择是让用户显式获取和释放行
  • 对于轻量级的类似 ORM 的插件,你尝试过 LINQ to SQL 吗?甚至将您的数据库更改为 MongoDB。使用 MongoDB,您可以使用具有类似 SQL 的查询功能的快速和基于集合的数据库获得乐趣。对于丰富的 ORM,可以使用 EntityFramework/NHibernate
  • 所有有趣的答案,但题外话。我不是在谈论数据存储在哪里。我说的是编写我自己的轻量级 ORM,它重用现有对象而不是创建重复对象。换句话说,NH和EF背后的基本存储是什么。有意义吗?

标签: c# database orm model


【解决方案1】:

一个选项是使用CSLA framework。它不是 ORM,它是一个“智能对象”框架。它对实体和后代实体的集合具有简单、高效的更改跟踪。它还具有几个可选功能,例如:

  1. 能够通过配置文件将应用程序配置为 2 层或 3 层应用程序。
  2. 基于角色的安全性。
  3. 正式的验证规则(包括对验证属性的支持)。
  4. 正式的业务规则(用于在实体之间同步数据)。
  5. 用于配置数据层的多个选项,支持任何数据持久性机制。
  6. 几乎支持 .NET 中的任何 UI 框架。
  7. 多个对象原型,包括只读或读写实体和集合。

缺点是学习框架有相当长的学习曲线(虽然有很好的文档),而且对 DI 或测试框架不太友好。

【讨论】:

  • +1 获取信息,因为它可能对一些人有所帮助,但我再次尝试简单且轻量级地做到这一点。将其视为编码学习练习。不过,再次感谢 CSLA 的提醒。
  • 很棒的信息,但只有一件事...实现 DI 或使您的业务对象可测试并不难...您可以通过覆盖默认 DataPortalActivator 并实现您的自定义 DataPortalActivator 来引入 DI...通过这样做,您将可以更好地控制业务对象实例的创建,因此您可以轻松地注入依赖项。
  • @Viru - 感谢您的提示。我将不得不调查这种方法。你知道任何有样本的在线文档吗?
  • @NightOwl888 我自己学得很辛苦,但我得到了这个链接,它给了我使用 DataPortalActivator 的初步想法。 magenic.com/Blog/Post/43/Abstractions-in-CSLA
  • @Viru - 感谢您的链接。不幸的是,这种方法只比我使用的方法好一点。我修改了 Jonny Bekkum 的 MEF 实现以使用 StructureMap 属性注入,方法是为每个对象构造型注入 DataPortal_OnDataPortalInvokeChild_OnDataPortalInvokeOnDeserialized。不幸的是,我们仍然被属性注入所困。然而,这种方法确实减少了很多框架集成代码,所以它绝对是一个改进。它还解决了我遇到的一些 UI 集成和生命周期问题。
猜你喜欢
  • 1970-01-01
  • 2018-02-09
  • 1970-01-01
  • 2012-04-14
  • 2011-03-21
  • 2010-11-23
  • 2023-03-20
  • 2011-02-16
相关资源
最近更新 更多