如何跟踪对业务对象的更改?
我得到了创建业务对象或者实体以表示诸如Person之类的概念。然后,我可以使用DTO序列化Person并将其发送给客户端。如果客户端更改了该对象,则该对象上可以有一个IsDirty标志,因此当它被发送回我知道要更新的服务器时。
但是,如果我有一个Order对象,该怎么办?它具有主要标头信息,客户,供应商,所需日期等。然后具有OrderItems,它是List <OrderItem>,是要订购的项目。我希望能够在我的UI上使用此业务对象。所以我有一些与位置,供应商,所需日期等相关的文本框,以及与OrderItems相关的网格。由于OrderItems是一个列表,因此我可以轻松地向其中添加和删除记录。但是我该如何跟踪,尤其是删除的项目。我不希望已删除的项目在网格中可见,并且如果我使用foreach,也应该无法对其进行迭代,因为它们已被删除。但是我仍然需要跟踪存在删除的事实。如何跟踪更改。我想我需要使用一个工作单元吗?但是随后,代码似乎变得非常复杂。因此,我想知道为什么不简单地使用DataTables并免费获得更改跟踪?但是后来我读到了业务对象是如何发展的。
Ive在简单的Person示例中发现了各种示例,但没有Orders这样的标头详细示例。
BTW为此使用C3.5.
解决方案
回答
数据对象不跟踪更改。更改跟踪发生在DataContext和我们通过DataContext检索到的对象上。因此,为了跟踪更改,我们需要执行以下操作:
public class FooDataContext : DataContext { public Table<Order> Orders; } public class Order { [DbColumn(Identity = true)] [Column(DbType = "Int NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true)] public int Id { get; set; } [DbColumn(Default = "(getutcdate())")] [Column(DbType = "DateTime", CanBeNull = false, IsDbGenerated = true)] public DateTime DateCreated { get; set; } [Column(DbType = "varchar(50)", CanBeNull = false, IsDbGenerated = false)] public string Name { get; set; } }
现在,在代码隐藏中,我们可以执行以下操作:
public void UpdateOrder(int id, string name) { FooDataContext db = new FooDataContext(); Order order = db.Orders.Where(o=>o.Id == id).FirstOrDefault(); if (order == null) return; order.Name = name; db.SubmitChanges(); }
我不建议直接在后面的代码中使用数据上下文,但这是使用Linq To SQL的好方法。我建议将所有数据库交互都放在一个外部项目中,并从GUI调用封装此行为的类。
如果我们不熟悉Linq To Sql,我建议我们创建一个Linq To Sql(dbml)文件。
在解决方案资源管理器中右键单击项目,然后选择添加新项。选择Linq To SQL文件,然后它将使我们连接到数据库并选择表。
然后,我们可以查看生成的代码,并获得有关Linq To Sql的工作方式以及如何使用它的一些很棒的想法。
将其用作使用Linq to SQL的指南,它将带我们进一步...
回答
首先,我们可以使用解决这些问题的现有框架,例如CSLA.NET。这个框架的作者已经解决了这些问题。为此,请访问http://www.rockfordlhotka.net/cslanet/。即使我们没有使用完整的框架,这些概念仍然适用。
如果我们想自己动手制作,过去我所做的就是使用集合从BindingList派生的自定义类型,而不是对集合使用List。从BindingList中进行插入允许我们覆盖添加/删除项目的行为。因此,例如,我们可以拥有另一个内部的"删除"项目。每次在集合上调用重写的Remove方法时,请将该项放入"已删除"集合中,然后调用Remove方法的基本实现。我们可以对添加的项目或者更改的项目执行相同的操作。
回答
我们会发现需要一个工作单元,但是不要编写一个工作单元。使用NHibernate或者其他一些ORM。那就是他们的目的。他们有内置的工作单元。
对于大多数应用程序而言,业务对象确实是"必经之路"。我们正潜入更深的领域,将会有很多要做的事情。查看DDD。
我也强烈建议我们不要在后面的代码中使用类似的代码。查看MVP模式。
我也(在我不愿意学习很多新的,非常关键的东西的同时)研究SOLID。
我们可能想查看JP Boodhoo的.net课程,因为它涵盖了很多此类内容。