LINQ加入前1名
我有三个对象(splistitemcollection),我将它们连接在一起,这非常有效,但我遇到的问题是,合同对象和客户对象之间存在一对多的关系。在加入过程中,我只需要为每个合同对象获取第一个customers对象 这是我得到的 (Contract)(Customer) 12345 John Smith 12345 Jane Smith 67890 howard Jones 67890 Mary Jones 在SQL中,我会在join上定义的子查询中定义一个select top子句,但我无法理解我的新手linq brain的语法 最终结果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子句,但
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);