【发布时间】: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背后的基本存储是什么。有意义吗?