【发布时间】:2009-05-28 22:24:41
【问题描述】:
很抱歉,这里到处都是……但我觉得自己就像一条追着我尾巴的狗,我现在都很困惑。
我正在尝试以最简洁的方式开发 3 层解决方案(IL、BL、DL),其中 DL 使用 ORM 来抽象对数据库的访问。
我所见过的任何地方,人们都使用 LinqToSQL 或 LLBLGen Pro 来生成代表 DB 表的对象,并在所有 3 层中引用这些类。 似乎 40 年的编码模式被忽略了——或者发生了范式转变,我错过了为什么这样做完全可以的解释部分。
然而,希望成为数据存储机制不可知论似乎仍有一些基础——看看 LinqToSQL 发生了什么:针对它编写了很多代码——仅适用于 MS 放弃它......所以我想尽可能地隔离 ORM 部分,只是不知道如何。
所以,回到绝对基础,以下是我希望以非常干净的方式组装的基本部分:
我开始的程序集: UL.dll BL.dll DL.dll
主要类:
具有公开 MessageAddress 对象集合(称为 MessageAddresses)的属性的 Message 类:
class Message
{
public MessageAddress From {get;}
public MessageAddresses To {get;}
}
每层的功能:
BL 向 UI 公开一个名为 GetMessage (Guid id) 的方法,该方法返回一个 Message 实例。
BL 依次包裹 DL。
DL 有一个包装了 Provider 实例的 ProviderFactory。 DL.ProviderFactory 公开(可能是我的问题的一部分)两个静态方法,称为 GetMessage(Guid id),和 SaveMessage(消息消息) 最终目标是能够将一个为 Linq2SQL 编写的提供程序替换为一个为 LLBLGen Pro 编写的提供程序,或者另一个不针对 ORM 工作的提供程序(例如 VistaDB)。
设计目标: 我想要层分离。 我希望每一层只依赖于它下面的层,而不是它上面的层。 我希望 ORM 生成的类仅在 DL 层中。 我希望 UL 与 BL 共享 Message 类。
因此,这是否意味着:
a) 消息在 BL 中定义 b) DB 表的 Db/Orm/Manual 表示(“DbMessageRecord”或“MessageEntity”,或其他 ORM 调用它)在 DL 中定义。 c) BL 依赖于 DL d) 在调用没有 ref 或不知道 BL 的 DL 方法之前,BL 必须将它们转换为 BL 实体(例如:DbMessageRecord)?
UL:
Main()
{
id = 1;
Message m = BL.GetMessage(id);
Console.Write (string.Format("{0} to {1} recipients...", m.From, m.To.Count));
}
BL:
static class MessageService
{
public static Message GetMessage(id)
{
DbMessageRecord message = DLManager.GetMessage(id);
DbMessageAddressRecord[] messageAddresses = DLManager.GetMessageAddresses(id);
return MapMessage(message,
}
protected static Message MapMessage(DbMessageRecord dbMessage. DbMessageAddressRecord[] dbAddresses)
{
Message m = new Message(dbMessage.From);
foreach(DbMessageAddressRecord dbAddressRecord in dbAddresses){
m.To.Add(new MessageAddress (dbAddressRecord.Name, dbAddressRecord.Address);
}
}
DL:
static class MessageManager
{
public static DbMessageRecord GetMessage(id);
public static DbMessageAddressRecord GetMessageAddresses(id);
}
问题: a) 显然,这迟早要做很多工作。 b) 更多错误 c) 较慢 d) 由于 BL 现在依赖于 DL,并且正在引用 DL 中的类(例如 DbMessageRecord),因此似乎由于这些是由 ORM 定义的,因此您不能删除一个提供程序,并用另一个提供程序替换它,...使整个练习变得毫无意义……还不如通过 BL 使用 ORM 的类。 e) 或者...在 BL 和 DL 之间需要另一个组件,并且需要另一个映射以使 BL 独立于底层 DL 类。
希望我能更清楚地提出问题......但我真的只是在这一点上迷路了。任何帮助将不胜感激。
【问题讨论】:
-
如果发生了范式转变,要么是人们意识到数据传输对象不是很干燥,要么可能是馄饨代码正在成为比千层面代码更流行的结构。
-
我认为千层面代码是使软件可扩展的唯一方法(我个人认为我不会知道,因为我不必处理这样的规模)。您是说 Ravioli Code + WCF 可以实现相同的效果,因此 Lasagna 代码层分离不再那么重要?无论如何——看不到如何使馄饨代码跨多个 ORM 提供程序模块化。似乎需要某种映射。顺便说一句,你让我饿了。
标签: c# design-patterns orm