您不能使用 LINQ lambda 查询语法来编写它。join
关键字要求您准确指定使用关键字比较的两个属性,因为这映射到使用默认比较器比较键equals
的第一个重载。Join
但是,Join
接受一个IEqualityComparer
可能对您有用的重载,您只需要使用方法查询语法。
由于您听起来对方法语法不熟悉,因此这里有一篇来自 MSDN 的不错的入门文章:
http://msdn.microsoft.com/en-us/library/vstudio/bb397947.aspx
但是,基本上,您认为“LINQ”的语法只是引用 LINQ 扩展的一种方式,实际上只是围绕IEnumerable
实现 LINQ 的扩展方法的语法糖。因此,例如,查询:
from x in y where x.IsActive orderby x.Name select x
它基本相同
y.Where(x => x.IsActive).OrderBy(x => x.Name).Select(x => x);
在大多数情况下,每个查询子句都映射到特定IEnumerable
方法的特定重载,但这些方法还有许多其他重载,它们采用不同数量和类型的参数。
这些Join
方法有点复杂,因为它们将两个序列作为输入,并让您使用表达式组合它们的各个元素,但想法完全相同。典型的联接如下所示:
from x in y
join a in b on x.Id equals a.ParentId
select new { x.Id, x.Name, a.Date }
变成
y.Join(
b,
x => x.Id,
a => a.ParentId,
(x, a) => new { x.Id, x.Name, a.Date });
这将加入a.ParentId
并x.Id
使用其数据类型(int、string 等)的默认比较。编译器直接将查询语法翻译成方法语法,因此两者的行为完全相同。(挑剔我自己的答案:从技术上讲,这些方法在Enumerable
类上,所以你真的在调用Enumerable.Join
. 但由于它们是作为扩展方法实现的,你可以用任何一种方式调用它们,编译器会弄清楚。)
在您的情况下,您需要传递不同的比较方法,以便您可以string.Compare
使用显式编码进行调用。的另一个重载Join
允许您提供一个实现IEqualityComparer<T>
来使用而不是默认值。这将要求您IEqualityComparer<string>
在一个单独的类中实现,因为没有简单的方法来创建匿名接口实现(可能是我从 Java 中错过的唯一功能)。对于你的例子,你想要这样的东西:
public class ComparerWithEncoding : IEqualityComparer<string>
{
private CompareInfo compareInfo
public ComparerWithEncoding ( string encoding )
{
this.compareInfo = CompareInfo.GetCompareInfo(encoding);
}
public bool Equals ( string a, string b )
{
return CompareInfo.Compare(a, b) == 0
}
public int GetHashCode(string a)
{
return a.GetHashCode();
}
}
classListA.Join(
ClassListB,
ObjA => ObjA.Name,
ObjB => ObjB.Name,
(ObjA, ObjB) => new { stringA = ObjA.Foo, stringB = ObjB.Bar },
new ComparerWithEncoding("es-ES"));