2012-03-18 37 views
2

我正在创建n层应用程序体系结构。不同的层不知道任何其他内部实现,层之间的通信通过IoC/DI辅助的非常狭窄的接口进行处理。如何将对象类型从业务层传递到数据层

现在我将业务对象(在业务层中定义)传递给数据层。业务层本身并不知道如何以及在何处保存数据(通常数据库,但业务层不应该知道这一点)。通过实施IDataReader将业务对象传递到数据层(此方法还支持将来场景中批量加载数据)。数据层读取IDataReader中的所有数据,并调用一些存储过程将数据保存到数据库(如果保存了一个对象,则IDataReader返回“一行”)。

实际的问题是在这里:

因为我传递的IDataReader以数据层和其类型断开数据,什么是在这种情况下,最好的办法,以确定地方的数据?

示例如果我将实际的“用户”类型的业务对象传递给数据层,那么数据层应该将数据保存到表“用户”中。在另外一些情况下,数据可能会保存到某个不同的结构中,而与业务层的类型无关。

在当前实现中,我将业务对象的类型信息传递到数据层和数据层,检查此类型并确定将数据放置在何处。

数据层检查传入数据并确定其位置或数据层是否应显示可以保存数据的“位置”列表(enum?)是否正确?

在此先感谢!

/澄清

选项,我在这里看到的是: 1.数据层提供了其中的数据可以保存 2.数据层给出巡视参数(如该类型ARG“plces”名单)以及存储数据的地点

第一种选择惩罚;如果我尝试将“产品”类型的商业对象存储到通常由类型“用户”使用的结构中,那么该怎么办?

第二种选择惩罚;我必须将类型“Namespace1.Namespace2.User”映射到将其数据保存到表“用户”的特定例程。所以手工做一些映射为每种类型的...

/澄清2:

现在我找回这样的:

service.Retrieve(typeof(Catalog), null, catalogArgs, e => catalogConverter.Read(e)); 

所以我通过typeof运算(目录)到数据层。 ..所以我有数据层的类型信息。

现在在数据层中,我需要选择难以从数据库中获取数据的“适配器”。我可以编写巨大的if/switch结构来选择适配器......这令人沮丧。我也可以写属性,并使用它像这样:

[TypeAdapterAttribute("Namespace1.Namespace2.Catalog, and assembly info...")] 
class CatalogAdapter { ... } 

然后,我有代码,不会从给定类型映射属性值...

...但它是一点点膨胀和问题,硬编码类型的字符串...

任何建议...?

/澄清3

我有想法,该系统可以通过“可插拔的业务模块”进行扩展。这些模块包含基本业务逻辑所不知道的业务对象(以及某些逻辑),数据层也完全不了解“插入的程序集”中包含的这些业务对象。此外部业务模块没有提及基础业务层或数据层。当此外部程序集的业务对象被保存(=发送到数据层)时,数据层默认将其保存为EAV样式(http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80% 93value_model)数据结构自动。由于这种数据结构可能存在一些性能问题,因此数据层必须有办法将特定业务对象类型保存在其自己的专用数据结构(通常是具有一对一映射的表)中。所以问题来了,如何实现这个“选择决定”:)

这里的想法是,我可以创建很多新的业务对象,我可以将它们全部保存到数据层,而不需要实际编码任何东西到数据层!之后,如果需要,我可以为选定的业务对象创建自己的专用数据结构。

+0

说明3描述了全新的先决条件并提出了一个全新的问题。您可以根据属性的数量进行决定。几个属性 - > EAV,很多属性 - >专用模型。您可以确定像这样的属性'PropertyInfo [] props = obj.GetType()。GetProperties();' – 2012-03-19 14:09:02

+0

那么,C3仍然是大约相同的系统。我只是试图澄清系统的目标。我想我可能会打开新的问题后,我一直在考虑这一点.... – Harza 2012-03-19 17:10:19

回答

1

我建议您使用ORM(Entitiy Framework,NHibernate)或micro-ORM(PetaPoco,Dapper)将您的对象映射到数据存储。
如果您有具体问题,请仔细研究并拍摄。

更新:我想我刚刚得到你所问的。
您需要为每种类型在数据层中定义一种新方法。 所以:

public User GetUserById(int id); 
public void SaveUser(User user); 
public Product GetProductById(int id); 
public void SaveProduct(Product product); 
+0

如果使用任何ORM,我仍然需要知道如何“选择实体从orm用于数据存储”... – Harza 2012-03-18 19:48:59

+0

由于任何实现都是ORM特定的,我不能给你一个通用的代码示例。你想做什么(将对象映射到表)是ORM的全部目的。我会说,看看PetaPoco,因为它非常简单。该文档是一个完整的代码示例页面。 – David 2012-03-18 20:06:01

+0

@Harza:是的,但是您不认为表格和专栏,而是关于您的业务对象及其属性。看我上面的例子。 – 2012-03-18 20:06:51

1

如果你想创建一个从业务层断开自己的数据库层,你也可以介绍与合同

List<Customer> customers = DB.LoadCustomers(); 

数据层可以用通用的工作一个单独的程序键入参数并通过Reflection获取有关业务对象的信息。这提供了层的良好分离,因为数据层不需要引用业务组件。

List<Customer> customers = DataContext.Query<Customer>.Load(); 

Customer customer = DataContext.Query<Customer>.Load(custID); 

O/R-映射器通常这样工作

List<Customer> customers = Context.Query<Customer>() 
    .Where(cust => cust.Name.StartsWith("A")) 
    .OrderBy(cust => cust.Name) 
    .ToList(); 

在这些实施例中,数据层创建并填充业务对象。否则,业务层必须知道表列名称。

(注意:这里我没有提到具体的数据接口。)


UPDATE:

如果你想创建一个从业务层diconnected自己的数据库层也可以引入与合同

public interface ICustomer 
{ 
    string LastName { get; set; } 
    string FirstName { get; set; } 
    ... 
} 

两个独立的组件,该数据层和业务层将有这些合同的参考。

在数据层,你会类似于

public List<T> LoadAll<T>(Func<T> create) 
{ 
    var list = new List<T>(); 
    if (T is ICustomer) { 
     string sql = "SELECT * FROM tblCustomer"; 
     ... 
     while (reader.NextResult()) { 
      ICustomer cust = (ICustomer)create(); 
      cust.FirstName = reader.GetString("FirstName"); 
      ... 
      list.Add((T)cust); 
     } 
    } else if (T is IOrder) { 
     ... 
    } 
    return list; 
} 

在业务层的方法,你会写

List<ICustomer> customers = DbLayer.LoadAll<ICustomer>(() => new Customer()); 

现在,你的数据层可以与客户不知道你的客户类并且没有对业务层组件的引用。

+0

解决方案尝试避免使用对象映射,数据通过使用IDataReader的层传输。在查询案例中,数据层将IDataReader提供给业务层,可用于读取数据并在需要时实现对象。使用IDataReader并不是问题,只是“如何告诉数据层类型来处理没有实际类型” – Harza 2012-03-18 19:59:58

+0

可能是这样的:'IDataReader customers = DataLayer.LoadAll(“Customers”);'。但是,您的业务层必须知道列名称。 – 2012-03-18 20:10:39

+0

在你的例子中,你通过字符串文字“Customers”告诉需要获取什么样的数据,这是这个问题的关键点。现在我正在做类似的事情,但使用System.Type作为参数。数据层然后以某种方式确定获得“客户”的方式。如果你需要命名空间,我只是尝试在这里解决最合适的解决方案(字符串,类型,别的东西).... – Harza 2012-03-18 20:24:21

相关问题