Linq相交或连接返回一个集合中与另一个集合具有匹配属性的项
本文关键字:集合 另一个 属性 一个 连接 返回 Linq | 更新日期: 2023-09-27 18:09:39
我有以下场景:两个不同的Types
列表恰好包含3个匹配的属性(实际上,名称不相同,因为它们来自不同的系统/数据库表,但它们的内容匹配)。
在我的例子中,我将属性命名为相同只是为了使它更容易!
我想获得Prefix+Number+Suffix
的帐户列表,在查找中有一个匹配的项目(注意:查找可以多次包含相同的值-对象中的其余属性不同)
这是我目前正在使用的代码,但感觉很笨拙。有没有一种更干净、更好的方法来达到同样的结果?我尝试了"Contains()",但不确定如何限制所有三个属性。
var accounts = new List<Account>{
new Account{Prefix="001", Number="10101", Suffix="666"},
new Account{Prefix="001", Number="10202", Suffix="777"},
new Account{Prefix="001", Number="10303", Suffix="777"},
new Account{Prefix="002", Number="20101", Suffix="666"},
new Account{Prefix="002", Number="20101", Suffix="777"}
};
var lookup = new List<Lookup>{
new Lookup{Prefix="001", Number="10101", Suffix="666"},
new Lookup{Prefix="001", Number="10101", Suffix="666"},
new Lookup{Prefix="002", Number="20101", Suffix="666"},
new Lookup{Prefix="001", Number="10101", Suffix="666"},
};
var match = ((from a in accounts
select a)
.Intersect(from l in lookup
from a in accounts
where l.Prefix == a.Prefix &&
l.Number == a.Number &&
l.Suffix == a.Suffix
select a)
).Select(a => string.Format("{0}{1}{2}", a.Prefix, a.Number, a.Suffix));
您可以使用以下代码来获得匹配:
var match = (from a in accounts
select new { P = a.Prefix, N = a.Number, S = a.Suffix })
.Intersect(from l in lookup
select new { P = l.Prefix, N = l.Number, S = l.Suffix })
.Select(t => string.Format("{0}{1}{2}", t.P, t.N, t.S));;
您在这里使用匿名类型上自动生成的相等操作符
为什么不直接:
match = (from l in lookup
from a in accounts
where l.Prefix == a.Prefix &&
l.Number == a.Number &&
l.Suffix == a.Suffix
select string.Format("{0}|{1}|{2}", l.Prefix, l.Number, l.Suffix))
.Distinct();
试试这个:
from a in accounts
join l in lookup on
new
{
a.Prefix, a.Number, a. Suffix
}
equals
new
{
l.Prefix, l.Number, l. Suffix
}
into gls
select a
在这种情况下,我不会直接使用表,而是使用数据库视图。创建一个视图,为您执行联合并返回一个规范化的数据结构,如下所示:
CREATE VIEW ExampleView
AS
SELECT
Prefix = a.Prefix,
Number = a.Number,
Suffix = a.Suffix
FROM
FirstTable AS a
UNION ALL
SELECT
Prefix = l.Prefix,
Number = l.NumberWithDifferentName,
Suffix = l.WeirdlyNamedSuffix
FROM
SecondTable AS l
然后你可以在这个视图上运行一个简单的选择,而不是在你的应用程序中执行复杂的数据库逻辑,无论如何它都不属于:
SELECT Prefix, Number, Suffix FROM ExampleView; /* or obviously the LINQ equivalent */
这里有一个关于这个问题的文章链接(为什么要使用视图):http://www.tdan.com/view-articles/5109。下面的部分解释了为什么最好的做法是让数据库做它最擅长的事情,而不是应用程序:
开发人员发现必须使用规范化的数据结构既尴尬又耗时,因为它涉及到编写复杂的SQL查询来连接来自多个表的数据。[…[/em>
你为什么不试试把它们连起来呢
from a in accounts
join l in lookup
on
new { a.Prefix, a.Number, a. Suffix}
equals
new { l.Prefix, l.Number,l. Suffix}
select a;