如何将对象的中间层连接到由DataSet组成的数据层?

时间:2020-03-06 14:53:22  来源:igfitidea点击:

我有一个中间层,其中包含几个相关的对象,另一个数据层则是使用具有多个DataTables和关系的DataSet。

我想在我的一个对象(父对象)上调用Save方法,并将其私有变量数据转换为DataRow并添加到DataTable中。某些私有变量数据实际上是其他对象(子对象),每个对象都需要调用自己的Save方法并保留自己的变量数据。

如何将它们"绑在一起"?应该在ParentObject中实例化DataSet的哪些部分,需要将哪些部分传递给ChildObject,以便它们可以将自己添加到数据集中?

另外,如何将两个表的关系关联在一起?

我为Order OrderDetail关系看到的示例创建OrderRow和OrderDetailRow,然后调用OrderDetailRow.SetParentRow(OrderDetail)

我认为这对我不起作用,因为我的Order和OrderDetail(使用其示例命名)位于单独的类中,并且示例均以Big Honking Method发生。

谢谢,
基思

解决方案

因此,我现在正在做的是将对DataSet的引用和对父级的DataRow的引用传递到子对象的Save方法中。

这是一些小代码,显示了我在做什么的概念。

// some random save event in a gui.cs//
public void HandleSaveButtonClick()
{ parentObject.Save(); }

// Save inside the parentObject.cs //
public void Save()
{    
    CustomDataSet dataSet = new CustomDataSet();

    ParentObjectTableAdapter parentTableAdapter = new ParentObjectTableAdapter();

    DataTable dt = dataSet.ParentTable;
    DataRow newParentDataRow = dt.NewRow();
    newParentDataRow["Property1"] = "Hello";
    newParentDataRow["Property2"] = "World";
    dt.Rows.Add(newParentDataRow);

    parentTableAdapter.Update(dataSet.ParentTable);

    //save children
    _child1.Save(dataSet, newParentDataRow)

    dataSet.AcceptChanges();
}

//Save inside child1.cs //
public void Save(CustomDataSet dataSet, DataRow parentRow)
{

    Child1TableAdapter childTableAdapter= new Child1TableAdapter();

    DataTable dt = dataSet.ChildTable;

    DataRow dr = dt.NewRow();
    dr.SetParentRow(parentRow);
    dr["CProp1"] = "Child Property 1";    
    dt.Rows.Add(dr);

    childTableAdapter.Update(dataSet.ChildTable);

}

让我知道这看起来如何。这是一种可用的模式还是我缺少一些关键的东西?

谢谢,
基思

我不会再讨论数据集是好是坏。如果继续使用它们,请考虑以下事项:

  • 我们需要保留原始数据集并对其进行更新,以获取正确的插入和更新。
  • 我们希望父母认识他们的孩子,但反之则不然。放下ParentTable。
  • 订单及其OrderDetails是汇总的(来自域驱动设计),应视为一个整体。调用order.Save()应该保存所有内容。

好吧,这就是理论。我们该怎么做?一种方法是创建以下工件:

  • 命令
  • 订单详情
  • OrderRepository
  • 订单图

OrderMap是我们管理"订单到数据集"关系的地方。在内部,它可以使用哈希表或者字典。

OrderRepository是我们从中获取订单的地方。存储库将从某个位置获取具有所有关系的数据集,使用其所有OrderDetails构建Order,并将Order / Dataset关系存储在OrderMap中。

只要Order处于活动状态,OrderMap就必须保持活动状态。
订单包含所有OrderDetails。

将订单传递到存储库,然后将其保存。存储库将从地图中获取数据集,从订单中更新Order-table,并迭代所有order-details以更新OrderDetail-table。

检索并保存:

var order = repository.GetOrder(id);
repository.Save(order);

内部OrderRepository.GetOrder():

var ds = db.GetOrderAndDetailsBy(id);
var order = new Order();
UpdateOrder(ds, order);
UpdateOrderDetails(ds, order); // creates and updates OrderDetail, add it to order.
map.Register(ds, order);

内部OrderRepository.Save():

var ds = map.GetDataSetFor(order);
UpdateFromOrder(ds, order);
foreach(var detail in order.Details) UpdateFromDetail(ds.OrderDetail, detail);

最后一些注意事项:

  • 我们可以将地图实现为singelton。
  • 让地图使用弱引用。然后,应在适当时对任何顺序进行垃圾收集,并释放内存。
  • 我们需要某种方式将OrderDetail及其表行关联
  • 如果极有可能升级到.NET 3.5,请执行此操作。 Linq to Sql或者Linq to Entity将消除某些痛苦。
  • 所有这些都是凭空产生的。我希望它不是太准确。