【问题标题】:Optimize queries for Union, Except, Join with LINQ and C#使用 LINQ 和 C# 优化 Union、Except、Join 的查询
【发布时间】:2012-01-23 16:43:03
【问题描述】:

我有 2 个对象(从 XML 加载的列表)reportdatabase(代码如下所示),我应该分析它们并根据 0、1、2、3 标记项目在某些情况下

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
                      };

【问题讨论】:

  • 其他人可以看到这个问题吗?

标签: linq join union except


【解决方案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&lt;&gt; 并将其提供给Contains() 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 1970-01-01
    • 2012-01-28
    相关资源
    最近更新 更多