提高linq查询的性能 - 尝试将查询从子查询更改为连接

时间:2017-06-27 19:33:41

标签: c# performance linq

我正在做下面的linq查询,这让我花了很多钱,这个查询处于一个我无法避免的循环中,我必须在C#中进行,这也是我无法避免的。我在linq查询之上和查询之后有很多逻辑。我想检查一下我是否可以更改查询上的任何内容,以至少提高性能。

lstDataTable.Where(i => i.Field<int>("ALLL_Snapshot_ID") == 20 && 
i.Field<int>("ALLL_Analysis_Segment_Group_Column_ID") == 5 &&
i.Field<DateTime>("OriginationDate") > startingSnapshotDate &&
i.Field<DateTime>("OriginationDate") <= endingSnapshotDate &&
snapshotDataWithDate.Select(j => j.Field<string>
("MaturityDateBorrowerIdNoteNumberKey")).Contains(i.Field<string>
("MaturityDateBorrowerIdNoteNumberKey")) &&
snapshotDataWithDate.Select(j => j.Field<string>
("OriginationDateBorrowerIdNoteNumberKey")).Contains(i.Field<string>
("OriginationDateBorrowerIdNoteNumberKey")))
.Select(i => i.Field<Decimal>("BalanceOutstanding") + i.Field<Decimal>
("UndisbursedCommitmentAvailability")).Sum();

其中lstDataTable和snapshotDataWithDate是DataRow的IEnumerable。

我尝试使用join进行上述查询,但未正确加入。两个结果之间的差异很大。以下是我尝试使用join

的查询
 (from p in lstDataTable
 join t in snapshotDataWithDate on p.Field<string>
 ("MaturityDateBorrowerIdNoteNumberKey") equals t.Field<string>
 ("MaturityDateBorrowerIdNoteNumberKey") && 
 p.Field<string>("OriginationDateBorrowerIdNoteNumberKey") equals 
 t.Field<string>("OriginationDateBorrowerIdNoteNumberKey")
 where p.Field<int>("ALLL_Analysis_Segment_Group_Column_ID") == 
 SegmentGroupCECLSurvivalRateObj.ALLL_Segment_Group_Column_ID &&
 p.Field<DateTime>("OriginationDate") > startingSnapshotDate && 
 p.Field<DateTime>("OriginationDate") <= endingSnapshotDate
 select p.Field<Decimal>("BalanceOutstanding") + p.Field<Decimal>
 ("UndisbursedCommitmentAvailability")).Sum();

2 个答案:

答案 0 :(得分:0)

尝试此查询,我在where子句中更改了一些表达式。

lstDataTable.Where(i => i.Field<int>("ALLL_Snapshot_ID") == 20 && 
i.Field<int>("ALLL_Analysis_Segment_Group_Column_ID") == 5 &&
i.Field<DateTime>("OriginationDate") > startingSnapshotDate &&
i.Field<DateTime>("OriginationDate") <= endingSnapshotDate &&
snapshotDataWithDate.Any(j => j.Field<string>
("MaturityDateBorrowerIdNoteNumberKey") == i.Field<string>
("MaturityDateBorrowerIdNoteNumberKey")) &&
snapshotDataWithDate.Any(j => j.Field<string>
("OriginationDateBorrowerIdNoteNumberKey") == i.Field<string>
("OriginationDateBorrowerIdNoteNumberKey")))
.Select(i => i.Field<Decimal>("BalanceOutstanding") + i.Field<Decimal>
("UndisbursedCommitmentAvailability")).Sum();

答案 1 :(得分:0)

或许撤出Field次访问会提供少量优化?

var snapshotDataConvertedMDB = snapshotDataWithDate.Select(r => r.Field<string>("MaturityDateBorrowerIdNoteNumberKey")).ToList();

var snapshotDataConvertedODB = snapshotDataWithDate.Select(r => r.Field<string>("OriginationDateBorrowerIdNoteNumberKey")).ToList();

var ans = lstDataTable
        .Select(r => new {
            ALLL_Snapshot_ID = r.Field<int>("ALLL_Snapshot_ID"),
            ALLL_Analysis_Segment_Group_Column_ID = r.Field<int>("ALLL_Analysis_Segment_Group_Column_ID"),
            OriginationDate = r.Field<DateTime>("OriginationDate"),
            MaturityDateBorrowerIdNoteNumberKey = r.Field<string>("MaturityDateBorrowerIdNoteNumberKey"),
            OriginationDateBorrowerIdNoteNumberKey = r.Field<string>("OriginationDateBorrowerIdNoteNumberKey"),
            BalanceOutstanding = r.Field<Decimal>("BalanceOutstanding"),
            UndisbursedCommitmentAvailability = r.Field<Decimal>("UndisbursedCommitmentAvailability")
        })
        .Where(i => i.ALLL_Snapshot_ID == 20 &&
                 i.ALLL_Analysis_Segment_Group_Column_ID == 5 &&
                 i.OriginationDate > startingSnapshotDate &&
                 i.OriginationDate <= endingSnapshotDate &&
                 snapshotDataConvertedMDB.Contains(i.MaturityDateBorrowerIdNoteNumberKey) &&
                 snapshotDataConvertedODB.Contains(i.OriginationDateBorrowerIdNoteNumberKey))
        .Select(i => i.BalanceOutstanding + i.UndisbursedCommitmentAvailability)
        .Sum();