0

我有一个实体类型,我们称之为事务,由实体框架版本 1 创建。我添加了以下属性:

public partial class Transaction
{
    public int CurrentMaxRevisionNumber { get; set; }
}

我有以下查询:

public List<Transaction> GetTransactions(DateTime startDate, DateTime endDate)
{
   var query = from t in Repository.Transaction  
       let currentMaxRevisionNumber = 
        Repository.Transaction.Where(t1 => t1.TransactionId == t.TransactionId)
                               .Max(t1 => t.RevisionNumber)
       where t.StartDate >= startDate
             && t.EndDate < endDate)
    select t;

    return query.ToList();
}

我们试图完成的业务规则如下:
- 应为原始日期的交易创建新记录,并使用代码表明它已被软删除并增加了修订号。
- 将在新日期创建交易的新记录,并增加修订号。

问题在于,确定何时处理交易的过程是一天一次地按顺序完成的,并且交易正在从一个日期移动到另一个日期,有时会不断地回到原来的状态。这可能导致给定事务的最大修订号将是特定日期的修订号,而不是事务的最大值。这就是我试图在查询中执行“让”的原因。

现在的问题是:
- 如何使用查询填充在部分类中创建的 CurrentMaxRevisionNumber 属性?
- 由于在任何给定日期可能有数百笔交易,我是否可以通过另一种方式来完成此操作而无需对每笔交易进行查询?

谢谢你的帮助。

4

1 回答 1

0

所以我尝试的第一件事是使用反模式 SELECT n + 1,这是一个可怕的解决方案,但至少这向我们表明,通过获取正确的数据,问题将得到解决。它是这样的:

public List<Transaction> GetTransactions(DateTime startDate, DateTime endDate)
{
   var list = (from t in Repository.Transaction  
       where t.StartDate >= startDate
             && t.EndDate < endDate)
    select t).ToList();

    foreach(var item in list)
    {
        item.CurrentMaxRevisionNumber = Repository.Transaction.
                                        Where(t => t.TransactionId == item.TransactionId).
                                        Max(t => t.RevisionNumber);
    }

    return list;
}

由于显而易见的原因,该解决方案是不可接受的,因此我们提出了以下建议:

public List<Transaction> GetTransactions(DateTime startDate, DateTime endDate)
{
   var query = (from t in Repository.Transaction       
       where t.StartDate >= startDate
             && t.EndDate < endDate)
    select new
    {
       OriginalTransaction = t,
       CurrentMaxRevisionNumber = Repository.Transaction.
                                        Where(t1 => t1.TransactionId == t.TransactionId).
                                        Max(t1 => t1.RevisionNumber);
    }).ToList();

    foreach(var item in list)
    {
       item.OriginalTransaction.CurrentMaxRevisionNumber = item.CurrentMaxRevisionNumber;
    }

    return list.Select(items => items.OriginalTransaction).ToList();
}

通过使用匿名对象,我们可以在单个数据库访问中获取我们需要的所有数据,并使用循环来填充缺失的属性。

由于我们必须修改数据库和应用程序的自由度受到一定限制,因此该解决方案被证明是侵入性最小且性能更高的解决方案。

于 2012-11-06T16:20:20.237 回答