本文介绍了ORM和层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起,这点是所有在这里的地方......但我觉得自己像一个狗追我的尾巴,我都在这一点上混淆。

Sorry for this point being all over the place here...but I feel like a dog chasing my tail and I'm all confused at this point.

我想看到开发3分层解决方案,其中DL是使用ORM抽象访问DB(IL,BL,DL)的最彻底的方法。

I'm trying to see the cleanest way of developing a 3 tiered solution (IL, BL, DL) where the DL is using an ORM to abstract access to a DB.

我到处都看到,人们用要么LinqToSQL或LLBLGEN Pro来产生代表数据库表的对象,并参考这些类中的所有3层。
好像40年编码模式已经被忽视 - 或者模式的转变已经发生了,我错过了explanaition一部分,为什么它完全确定这样做。

Everywhere I've seen, people use either LinqToSQL or LLBLGen Pro to generate objects which represent the DB Tables, and refer to those classes in all 3 layers.Seems like 40 years of coding patterns have been ignored -- or a paradigm shift has happened, and I missed the explanaition part as to why its perfectly ok to do so.

不过,似乎仍有一定的基础,渴望幸福的数据存储机制无关 - 是什么刚好LinqToSQL:大量的代码编写反对 - 只为MS
砸...所以我想ORM的一部分,尽我所能,只是不知道如何隔离开来。

Yet, it appears that there is still some basis to desiring being data storage mechanism agnostic -- look what just happened to LinqToSQL: a lot of code was written against it -- only for MSto drop it... So I would like to isolate the ORM part as best I can, just don't know how.

所以,要回绝对基础,这里有我想基本的部分已经组建了一个非常非常干净的方式:

So, going back to absolute basics, here are the basic parts that I wish to have assembled in a very very clean way:

我是从开始的大会:
UL.dll
BL .DLL
DL.dll

The Assemblies I'm starting from:UL.dllBL.dllDL.dll

主要课程:

这有一个属性的消息类揭露MessageAddress对象的集合(被称为MessageAddresses):

A Message class that has a property exposing collection (called MessageAddresses) of MessageAddress objects:

class Message 
{
    public MessageAddress From {get;}
    public MessageAddresses To {get;}
}

每个功能层:

BL暴露于所谓的GetMessage(GUID ID),它返回信息的一个实例的UI的方法

The BL exposes a Method to the UI called GetMessage (Guid id) which returns an instance of Message.

在BL又包装了DL。

DL具有一个包装提供实例ProviderFactory。
的DL.ProviderFactory自曝(可能是......我的问题的一部分)两个静态方法称为
的GetMessage(GUID ID)和
SaveMessage(消息消息)
的最终目标将是能够换出被用于LINQ2SQL为LLBLGEN临写为一个提供者,或者是不针对一个ORM(例如VistaDB的)工作其他提供商。

The DL has a ProviderFactory which wraps a Provider instance.The DL.ProviderFactory exposes (possibly...part of my questions) two static methods called GetMessage(Guid id), and SaveMessage(Message message)The ultimate goal would be to be able to swap out a provider that was written for Linq2SQL for one for LLBLGen Pro, or another provider that is not working against an ORM (eg VistaDB).

设计目标:
我想层的分离。
我想每一层只依赖于它下面层,而不是它上面。
我想ORM生成的类是仅在DL层。
我想UL与大家分享BL消息类

Design Goals:I would like layer separation. I would like each layer to only have dependency on layer below it, rather than above it.I would like ORM generated classes to be in DL layer only.I would like UL to share Message class with BL.

因此,这是否意味着:

A)消息在BL
B定义)的DB /奥姆/手动数据库表('DbMessageRecord'或'MessageEntity,或任何其他ORM调用它)的代表在DL定义。
C)的BL对DL
D依赖性)调用的DL方法之前,不具有ref或了解BL的BL具有到它们转换BL实体(例如:DbMessageRecord)

a) Message is defined in BLb) The Db/Orm/Manual representation of the DB Table ('DbMessageRecord', or 'MessageEntity', or whatever else ORM calls it) is defined in DL.c) BL has dependency on DLd) Before calling DL methods, that do not have ref or know about BL, the BL has to convert them BL entities (eg: DbMessageRecord)?

UL:

Main() 
{
    id = 1;
    Message m = BL.GetMessage(id);
    Console.Write (string.Format("{0} to {1} recipients...", m.From, m.To.Count));
}



BL:

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的类。定)或...需要$ B $另一个程序集的BL和DL之间为了留下底层DL类BL独立需要其他映射。

Questions:a) Obviously this is a lot of work sooner or later.b) More bugs c) Slowerd) Since BL now dependency on DL, and is referencing classes in DL (eg DbMessageRecord), it seems that since these are defined by ORM, that you can't rip out one Provider, and replace it with another, ...which makes the whole exercise pointless...might as well use the classes of the ORM all through the BL.e) Or ...another assembly is needed in between the BL and DL and another mapping is required in order to leave BL independent of underlying DL classes.

希望我能更清楚地提出问题......但我真的只是失去了在这一点上。任何帮助将不胜感激。

Wish I could ask the questions clearer...but I'm really just lost at this point. Any help would be greatly appreciated.

推荐答案

这个概念,你似乎缺少的是IOC / DI(即控制/依赖反转注射)。相反,使用静态方法,每个层应该只依赖于下一层的的接口的上,注射到构造实际的实例。你可以打电话给你的DL库,供应商或其他任何东西,只要它是底层的持久性机制的一个干净的抽象。

The concept you seem to be missing is IoC / DI (i.e. Inversion of Control / Dependency Injection). Instead of using static methods, each of your layers should only depend on an interface of the next layer, with actual instance injected into the constructor. You can call your DL a repository, a provider or anything else as long as it's a clean abstraction of the underlying persistence mechanism.

至于代表的实体对象(粗略地映射表)我强烈反对有两组对象(一个数据库特有的,一个没有)。它是确定为他们所有三层只要他们波苏斯引用(他们真的不应该知道他们在坚持),或者甚至的DTO(纯结构,没有任何行为)。使他们的DTO适合您的BL理念更好的,但是我喜欢有我的业务逻辑在我的域对象蔓延(面向对象式),而不是让BL(下称微软式)的概念。

As for the objects that represent the entities (roughly mapping to tables) I strongly advise against having two sets of objects (one database-specific and one not). It is OK for them to be referenced by all three layers as long as they are POCOs (they should not really know they're persisted), or, even DTOs (pure structures with no behavior whatsoever). Making them DTOs fits your BL concept better, however I prefer having my business logic spread across my domain objects ("the OOP style") rather than having notion of the BL ("the Microsoft style").

不知道有关LLBLGEN,但NHibernate的+任意的IoC像SpringFramework.NET或温莎提供干净漂亮的模型支持这一点。

Not sure about Llblgen, but NHibernate + any IoC like SpringFramework.NET or Windsor provide pretty clean model that supports this.

这篇关于ORM和层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 15:25