我有一个C#程序,它将数据库中的产品列表加载到产品对象列表中。用户可以通过我的程序界面添加新产品,编辑产品和删除产品。相当标准的东西。我的问题涉及跟踪这些更改并将其保存回数据库。在了解细节之前,我知道使用Entity Framework或NHiberate之类的东西可以解决跟踪添加和编辑的问题,但我认为这不会解决跟踪删除的问题。除了想要将大型代码转换为使用实体框架或NHiberate之外,我还想知道为了我自己的好奇而回答这个问题。保存数据库实体
为了跟踪编辑,我在做产品上的阶级是这样,我设置IsDirty标志一个属性更改的任何时间:
class Product
{
public bool IsDirty { get; set; }
public bool IsNew { get; set; }
// If the description is changed, set the IsDirty property
public string Description
{
get
{
return _description;
}
set
{
if (value != _description)
{
this.IsDirty = true;
_description = value;
}
}
}
private string _description;
// ... and so on
}
当我创建一个新的产品对象,我设置它的IsNew标志,以便程序知道在下次用户保存时将其写入数据库。一旦我成功将产品写入数据库,我就清除它的IsNew和IsDirty标志。
为了跟踪其删除,我做了一个列表类,跟踪已删除的项目:
class EntityList<T> : List<T>
{
public List<T> DeletedItems { get; private set; }
EntityList()
{
this.DeletedItems = new List<T>();
}
// When an item is removed, track it in the DeletedItems list
public new bool Remove(T item)
{
this.DeletedItems.Add(item);
base.Remove(item);
}
}
// ...
// When I work with a list of products, I use an EntityList instead of a List
EntityList<Product> products = myRepository.SelectProducts();
每一次我的产品列表保存到数据库中,我经历了所有的产品在EntityList的迭代。 DeletedItems属性并从数据库中删除这些产品。一旦列表成功保存,我将清除DeletedItems列表。
所有这些工作,但它似乎我可能做了太多的工作,特别是跟踪删除的项目,并记住每次创建一个新的产品对象时设置IsNew标志。我无法在Product的构造函数中设置IsNew标志,因为如果从数据库加载Product对象,我不想设置该标志。我也不会感到兴奋,因为我必须在任何地方使用我的EntityList类而不是使用List。
看起来这种情况非常普遍,但我一直无法通过我的研究找到一种优雅的方式。所以我有两个问题:
1)假设我没有使用Entity Framework之类的东西,是否有更好的方法来跟踪添加,编辑和删除,然后将这些更改持久化到数据库?
2)我是否正确地说,即使使用实体框架或NHiberate,我仍然必须编写一些额外的代码来跟踪我的删除项目?
由于实体框架正在存储我的数据的快照,这会产生多少开销?它是否实质上存储了每个对象两次(当前的工作副本和原始副本),因此使用的内存量增加了一倍? –
它将副本存储为值列表,工作副本是实现的对象以及您使用的对象。这是开销吗?这是整个过程中不可或缺的一部分。无论如何,总是建议使用短期的上下文(或会话),否则它们会变得非常沉重而且很慢。 –