【问题标题】:LINQ Join on top 1LINQ 加入前 1
【发布时间】:2010-10-25 13:13:12
【问题描述】:

我将三个对象(splistitemcollection)连接在一起,效果很好,但我遇到的问题是合同对象和客户对象之间存在一对多的关系。在加入期间,我只需要为每个合同对象获取第一个客户对象。

这是我得到的

(合同)(客户) 12345 约翰·史密斯 12345 简·史密斯 67890霍华德琼斯 67890 玛丽琼斯

这就是我想要的 12345(只是其中一位客户,简或约翰)

这是我当前使用的代码。

  var joinedResults = from SPListItem contracts in _contractList
                      join SPListItem customers in _customerList
                      on contracts["ContractNumber"] equals customers["ContractNumber"]  
                      join SPListItem loans in _loanList
                      on contracts["ContractNumber"] equals loans["Contract_x0020_Number"] 
                      into l from loans in l.DefaultIfEmpty()
                      select new MergedData(contracts, customers, loans);

在 SQL 中,我会在我的联接中定义的子查询中定义一个 select top 子句,我只是无法理解我的新手 linq 大脑的语法。

最终结果

  var joinedResults = from SPListItem contracts in _contractList
      join SPListItem customers in 
      // Derived subset
        (from SPListItem customers in _customerList
        group customers by customers["ContractNumber"] into groupedCustomers 
        select groupedCustomers.FirstOrDefault()
      )  on contracts["ContractNumber"] equals customers["ContractNumber"]  
      join SPListItem loans in _loanList
      on contracts["ContractNumber"] equals loans["Contract_x0020_Number"] into l
      from loans in l.DefaultIfEmpty()
      select new MergedData(contracts, customers, loans);

【问题讨论】:

  • 感谢大家的帮助。使用组概念,我能够得到我需要的结果。我实际上将 teh 组从单独的语句移动到查询中的内联。这是结果

标签: linq join object


【解决方案1】:

我将首先解释它,因为 LINQ 有时看起来令人困惑。这个想法是让您的客户查询,并按 ContractNumber 分组,然后取第一个。如果您希望您可以按某个字段排序,使其更具确定性(始终以字母顺序排列最低的名称等)然后您只需加入您的tempQuery,这基本上是 distinct(ContractNumber) 和第一个客户.

var tempQuery =  from SPListItem customers in _customerList
    group customers by customers["ContractNumber"] into gby 
    select gby.First();


var joinedResults =

    from SPListItem contracts in _contractList
    join SPListItem customer in tempQuery
on contract["ContractNumber"] equals customer["ContractNumber"]
    join SPListItem loans in _loanList
on contracts["ContractNumber"] equals loans["Contract_x0020_Number"] 
into l from loans in l.DefaultIfEmpty()
select new MergedData(
     contracts, 
     customer, 
     loans
   );

}

【讨论】:

  • 非常感谢,我当然更了解概念,而不仅仅是代码语法,而且打破分离当然是有意义的,我想这也会带来更快的性能不必加入每一行,然后只过滤第一行。
  • 我的 SP 虚拟机今天早上玩得不太好,所以我刚刚测试了上面的内容(使用 ListItemCollection 和 ListItem),它应该可以满足您的需求。以上说得通吗?
【解决方案2】:
var joinedResults =   (from SPListItem contracts in _contractList
                      join SPListItem customers in _customerList
                      on contracts["ContractNumber"] equals customers["ContractNumber"]  
                      join SPListItem loans in _loanList
                      on contracts["ContractNumber"] equals loans["Contract_x0020_Number"] 
                      into l from loans in l.DefaultIfEmpty()
                      select new MergedData(contracts, customers, loans)).FirstOrDefault();

只需调用 FirstOrDefault 方法来选择找到的第一个项目。

【讨论】:

  • 感谢您的回答,我意识到我遗漏了我描述的关键部分。我想要合同中的所有记录,并且只想要来自客户的匹配记录之一。所以基本上 FirstOrDefault 是正确的,但仅限于客户。这样的东西有用吗?
【解决方案3】:

这就像对每个返回的合约的 Top (1) 点查询:

var joinedResults = from SPListItem contracts in _contractList
                      join SPListItem loans in _loanList
                      on contracts["ContractNumber"] equals loans["Contract_x0020_Number"] 
                      into l from loans in l.DefaultIfEmpty()
                      select new MergedData(contracts, 
                      customer = _customerList.Where( c => c["ContractNumber"] == contracts["ContractNumber"].FirstOrDefault()
                      , loans);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多