我有一个实现IEquatable接口的OrderDto类。 我有一个从数据库中检索的订单列表,这些订单作为 OrderDto 对象。 此列表由最终用户编辑...添加新对象;删除现有对象;编辑现有对象。 我需要确定以下内容:
- 列表中的新对象;
- 列表中已删除的对象;
- 列表中已编辑的对象;
我已经注释了以下代码来讨论这三个目标。 前两项是微不足道的,但我列表中的第三项非常烦人! 我似乎无法使用 linq 创建它。 我希望你能在正确的方向上给我一个推动。 有关详细信息,请参阅以下代码。
感谢您的帮助!话筒
// Get the original list of OrderDtos before the user did anything.
var entityOrders = Mapper.Map<IList<OrderEntity>, IList<OrderDto>>(entity.Orders.ToList());
// dto.Orders is a parameter that is being used in this code. It is the list of OrderDto
// objects that the user has modified: Insert, edit, delete.
// Works properly to locate items that were deleted.
var deletedOrders = entityOrders.Except(dto.Orders);
// Works properly to locate items that were added.
var addedOrders = dto.Orders.Except(entityOrders);
// Determine the list of order objects less new orders in the list.
// The user has already deleted objects, so we don't have to worry
// about them. This list will contain only items that MAY have
// been edited.
var potentialChanges = dto.Orders.Except(addedOrders);
// ARGGG! I cannot seem to get this one to work properly! As you can see in the
// definition of the OrderDto, it implements the IEquatable interface. So, it
// should be very easy to determine which items in the dto.Orders list have been
// edited as opposed to the original version in the entityOrders list. What I
// would like to have is a list of all the OrderDto objects in the dto.Orders list
// that have been modified. Since OrderDto implements IEquatable, we should be able
// to compare OrderDto objects directly, but I have not been able get it to work.
// Please helP! :)
var changedOrders =
from dtoOrder in potentialChanges
let entityOrder = entityOrders.First(x => x.OrderId == dtoOrder.OrderId)
where entityOrder != null && !dtoOrder.Equals(entityOrder)
select dtoOrder;
以下是 OrderDto 类的定义...
public class OrderDto : IEquatable<OrderDto>
{
public long OrderId { get; set; }
public string DisplayAs { get; set; }
#region IEquatable
public override int GetHashCode()
{
// Populate with all fields so
// we can detect when an entity
// has been edited.
return
(
(int) OrderId ^
DisplayAs.GetHashCode()
);
}
public override bool Equals(object other)
{
return this.Equals(other as OrderDto);
}
public bool Equals(OrderDto other)
{
// Populate with all fields so
// we can detect when an entity
// has been edited.
return
(
other != null &&
other.OrderId == this.OrderId &&
other.DisplayAs == this.DisplayAs
);
}
#endregion
}
最简单的方法可能是包含 State
属性,例如值 New, Saved, Loaded, Modified
。您还可以添加IsDeleted
属性。
然后,实现设置为引发PropertyChanged
事件的每个属性,并实现自动将 State
属性设置为 Modified
的事件处理程序。
稍后您可以轻松查询:
var modified = entityOrders.Where(x => x.State == EntityState.Modified);
这种方法的优点是非常刻意的,即,你是明确的,代码是可读的,而不是试图变得困难(并且编写太多和太复杂的代码)。
以同样的方式,您可以实现一个 Delete() 方法,该方法只是将实体标记为已删除,并将所有已删除的实体查询为:
var deleted = entityOrders.Where(x => x.IsDeleted);
或
// ignore objects that were created, then deleted, without saving
var deleted = entityOrders.Where(x => x.IsDeleted && x.State != x.New);
以及所有有效数据:
var data = entityOrders.Where(x => !x.IsDeleted);