优化Union的查询,除了,使用LINQ和C#加入

时间:2011-12-19 15:06:59

标签: linq join union except

我有2个对象(从XML加载的列表)reportdatabase(在代码中显示如下),我应该分析它们并使用 0,1,2,3 <标记项目< / em>根据某些条件

TransactionResultCode = 0; // SUCCESS (all fields are equivalents: [Id, AccountNumber, Date, Amount])
TransactionResultCode = 1; // Exists in report but Not in database 
TransactionResultCode = 2; // Exists in database but Not in report 
TransactionResultCode = 3; // Field [Id] are equals but other fields [AccountNumber, Date, Amount] are different.

如果有人能抽出时间建议如何优化某些查询,我会很高兴。 贝娄是代码:

谢谢!!!

        //TransactionResultCode = 0 - SUCCESS
        //JOIN on all fields
        var result0 = from d in database
                      from r in report
                      where (d.TransactionId == r.MovementID) &&
                             (d.TransactionAccountNumber == long.Parse(r.AccountNumber)) &&
                             (d.TransactionDate == r.MovementDate) &&
                             (d.TransactionAmount == r.Amount)
                      orderby d.TransactionId
                      select new TransactionList()
                      {
                          TransactionId = d.TransactionId,
                          TransactionAccountNumber = d.TransactionAccountNumber,
                          TransactionDate = d.TransactionDate,
                          TransactionAmount = d.TransactionAmount,
                          TransactionResultCode = 0
                      };

        //*******************************************
       //JOIN on  [Id] field
       var joinedList = from d in database
                         from r in report
                         where d.TransactionId == r.MovementID
                         select new TransactionList()
                         {
                             TransactionId = d.TransactionId,
                             TransactionAccountNumber = d.TransactionAccountNumber,
                             TransactionDate = d.TransactionDate,
                             TransactionAmount = d.TransactionAmount
                         };

        //Difference report - database 
        var onlyReportID = report.Select(r => r.MovementID).Except(joinedList.Select(d => d.TransactionId));

        //TransactionResultCode = 1 - Not Found in database
        var result1 = from o in onlyReportID
                      from r in report
                      where (o == r.MovementID)
                      orderby r.MovementID
                      select new TransactionList()
                      {
                          TransactionId = r.MovementID,
                          TransactionAccountNumber = long.Parse(r.AccountNumber),
                          TransactionDate = r.MovementDate,
                          TransactionAmount = r.Amount,
                          TransactionResultCode = 1
                      };

        //*******************************************

        //Difference database - report 
        var onlyDatabaseID = database.Select(d => d.TransactionId).Except(joinedList.Select(d => d.TransactionId));

        //TransactionResultCode = 2 - Not Found in report
        var result2 = from o in onlyDatabaseID
                      from d in database
                      where (o == d.TransactionId)
                      orderby d.TransactionId
                      select new TransactionList()
                      {
                          TransactionId = d.TransactionId,
                          TransactionAccountNumber = d.TransactionAccountNumber,
                          TransactionDate = d.TransactionDate,
                          TransactionAmount = d.TransactionAmount,
                          TransactionResultCode = 2
                      };

        //*******************************************

        var qwe = joinedList.Select(j => j.TransactionId).Except(result0.Select(r => r.TransactionId));

        //TransactionResultCode = 3 - Transaction Results are different (Amount, AccountNumber, Date, )
        var result3 = from j in joinedList
                      from q in qwe
                      where j.TransactionId == q
                      select new TransactionList()
                      {
                          TransactionId = j.TransactionId,
                          TransactionAccountNumber = j.TransactionAccountNumber,
                          TransactionDate = j.TransactionDate,
                          TransactionAmount = j.TransactionAmount,
                          TransactionResultCode = 3
                      };

1 个答案:

答案 0 :(得分:1)

您可以尝试以下内容:

public void Test()
{
    var report = new[] {new Item(1, "foo", "boo"), new Item(2, "foo2", "boo2"), new Item(3, "foo3", "boo3")};
    var dataBase = new[] {new Item(1, "foo", "boo"), new Item(2, "foo22", "boo2"), new Item(4, "txt", "rt")};

    Func<Item, bool> inBothLists = (i) => report.Contains(i) && dataBase.Contains(i);
    Func<IEnumerable<Item>, Item, bool> containsWithID = (e, i) => e.Select(_ => _.ID).Contains(i.ID);

    Func<Item, int> getCode = i =>
                                    {
                                        if (inBothLists(i))
                                        {
                                            return 0;
                                        }
                                        if(containsWithID(report, i) && containsWithID(dataBase, i))
                                        {
                                            return 3;
                                        }
                                        if (report.Contains(i))
                                        {
                                            return 2;
                                        }
                                        else return 1;
                                    };

    var result = (from item in dataBase.Union(report) select new {Code = getCode(item), Item = item}).Distinct();
}

public class Item
{
    // You need also to override Equals() and GetHashCode().. I omitted them to save space
    public Item(int id, string text1, string text2)
    {
        ID = id;
        Text1 = text1;
        Text2 = text2;
    }

    public int ID { get; set; }
    public string Text1 { get; set; }
    public string Text2 { get; set; }
}

请注意,您需要为您的项目实施Equals(),或者实施IEqualityComparer<>并将其提供给Contains()方法。