LINQ加入前1名

LINQ加入前1名,linq,join,object,Linq,Join,Object,我有三个对象(splistitemcollection),我将它们连接在一起,这非常有效,但我遇到的问题是,合同对象和客户对象之间存在一对多的关系。在加入过程中,我只需要为每个合同对象获取第一个customers对象 这是我得到的 (Contract)(Customer) 12345 John Smith 12345 Jane Smith 67890 howard Jones 67890 Mary Jones 在SQL中,我会在join上定义的子查询中定义一个select top子句,但

我有三个对象(splistitemcollection),我将它们连接在一起,这非常有效,但我遇到的问题是,合同对象和客户对象之间存在一对多的关系。在加入过程中,我只需要为每个合同对象获取第一个customers对象

这是我得到的

(Contract)(Customer) 12345 John Smith 12345 Jane Smith 67890 howard Jones 67890 Mary Jones 在SQL中,我会在join上定义的子查询中定义一个select top子句,但我无法理解我的新手linq brain的语法

最终结果

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

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

我将首先解释它,因为LINQ有时看起来很混乱。这样做的目的是让您的客户进行查询,并根据合同编号进行分组,然后进行第一次查询。如果您希望您可以按某个字段进行订购,以使其更具确定性(总是按字母顺序取最低的名称,等等),那么您只需加入
tempQuery
,它基本上是不同的(合同编号)和第一个客户

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

}
这类似于对返回的每个合同的顶部(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);

谢谢你的回答,我意识到我的描述遗漏了一个关键部分。我想要合同中的所有记录,并且只需要客户的一个匹配记录。所以基本上FirstOrDefault是正确的,但只适用于客户。你喜欢这项工作吗?非常感谢,我当然更喜欢概念理解,而不仅仅是代码语法,这当然有助于打破分离,我想这也会提高性能,而不必加入每一行,然后只过滤第一行。我的SP VM今天早上表现不好,所以我刚刚测试了上面的内容(使用ListItemCollection和ListItem),它应该可以满足您的需要。以上有意义吗?谢谢大家的帮助。使用小组概念,我能够得到我需要的结果。实际上,我将组从一个单独的语句移动到了查询中的内联语句。结果如下
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
   );

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