[英]LINQ join and orderby issues
好吧,我已经为此奋斗了几天,研究LINQ之后,我认为我走对了。 但是我有一个SQL头脑,有时很难转换为C#。
我有两个数组,一个按字母顺序排序,另一个按ID排序。 我需要按字母顺序排列第二个数组。 ID是连接因素。 IEAID =P.ID。
这是我的数组和示例值;
private IGenericListItem[] _priceLevels = new IGenericListItem[0];
_priceLevels is in the form of {ID, Name}
{3, A}
{8, B}
{4, C}
{7, D}
{5, E}
{9, F}
{1, G}
编辑:更新此内容以显示_assignmentControls包含一个子数组。 我没有那么疯狂的借口。 它实际上包含_priceLevels的副本...
protected ArrayList _assignmentControls = new ArrayList();
_assignmentControls is in the form of {ID, LastPrice, NewPrice, _priceLevels[]}
{1, 1.00, 2.00, _priceLevels}
{2, 1.00, 2.00, _priceLevels}
{3, 1.00, 2.00, _priceLevels}
{4, 1.00, 2.00, _priceLevels}
部分原因是我试图比较/加入ArrayList和IGenericListItem。
In SQL I would do something like this;
SELECT A.*
FROM _assignmentControls A JOIN _priceLevels P
ON A.ID = P.ID
ORDER BY P.Name
这会给我一个_assignmentControls表,该表按_priceLevels中的值排序。
在C#LINQ中,我已经走了很远,但似乎无法正确解决。
var sortedList =
from a in _assignmentControls
join p in _priceLevels on a equals p.ID
orderby p.Name
select _assignmentControls;
我在join和orderby下出现红色弯曲,p.Name中的p为红色。 和A)它不起作用。 B)我不确定它将返回sortedList作为按_priceLevels.Name排序的_assignmentControls的排序版本。
编辑:当我将鼠标悬停在“联接”上时,我得到“无法从查询中推断方法'IEnumerable System.Linq.Enumerable.Join(此Enumerable,IEnumerable,Func,Func ....'的类型参数。我是现在研究。
感谢您的光临!
当我将鼠标悬停在“ join”上时,我得到“方法
IEnumerable System.Linq.Enumerable.Join(this Enumerable,IEnumerable, Func,Func....
无法从查询中推断出IEnumerable System.Linq.Enumerable.Join(this Enumerable,IEnumerable, Func,Func....
的类型参数。
我可以解释这里发生了什么,以便您可以对其进行跟踪。
当你说
from firstitem in firstcollection
join seconditem in secondcollection on firstkey equals secondkey
select result
编译器将其转换为:
Enumerable.Join(
firstcollection,
secondcollection,
firstitem=>firstkey,
seconditem=>secondkey,
(firstitem, seconditem)=>result)
Enumerable.Join
是具有四个类型参数的通用方法:第一个集合的元素类型,第二个集合的元素类型,键类型和结果类型。
如果遇到该错误,那么根据您提供给编译器的信息,就无法推断出这四件事之一。 例如,也许:
最后一点是最有可能的。 例如,假设第一个键为int
,第二个键为short
。 由于每个short
都可以转换为int
,因此int
将获胜,第二个键将自动转换为int
。 现在假设第一个键类型是Giraffe
,第二个键类型是Tiger
。 两者都不比另一个更好。 C#不会说“哦,它们都是Animal
,所以让我们选择它。” 而是说您没有提供足够的信息来确定您的意思。 您应该将其中之一投给Animal
,然后变得很清楚。
说得通?
我有一个半小时的视频,早在2006年就解释了此功能-这是我将有问题的功能添加到编译器中时的情况-因此,如果您需要更深入的说明,请查看。
http://ericlippert.com/2006/11/17/a-face-made-for-email-part-three/
更新:我只是再次仔细阅读了您的问题:
部分原因是我尝试比较/加入
ArrayList
和IGenericListItem
。
有问题。 无法从ArrayList
确定序列的类型。 您不应再使用ArrayList
。 实际上,您不应在2005年之后编写的任何代码中使用它。对于某些合适的T,请使用List<T>
。
您的select
子句是错误的,应该是这样的:
var sortedList =
from a in _assignmentControls
join p in _priceLevels on a equals p.ID
orderby p.Name
select a;
另一个问题是, _assignmentControls
的类型是ArrayList
,其中有一个类型的元素Object
,所以编译器不知道实际类型的a
,既然不能用它作为连接标准a
不具有类型相同p.ID
您应该使用List<int>
(假设p.ID
为int
类型)而不是ArrayList
。 另一个选项是指定的类型, a
明确的:
var sortedList =
from int a in _assignmentControls
join p in _priceLevels on a equals p.ID
orderby p.Name
select a;
我想你应该写:
var sortedList =
from a in _assignmentControls
join p in _priceLevels on a.ID equals p.ID
orderby p.AnotherValue
select a;
当您从_assignmentControls中的a编写时,您正在声明一个变量,该变量以要对其执行操作的顺序引用当前元素。 当调用select时,您将从序列中投影元素。 想象它像传送带。
让我给你一些转储数据的例子:
public class SomeCLass
{
public int ID { get; set; }
public string Name { get; set; }
}
public class AnotherClass
{
public int ID { get; set; }
public int Value { get; set; }
public int AnotherValue { get; set; }
}
public void TestMEthod()
{
List<SomeCLass> _assignmentControls = new List<SomeCLass>()
{
new SomeCLass() { ID = 1, Name = "test"},
new SomeCLass() { ID = 2, Name = "another test"}
};
List<AnotherClass> _priceLevels = new List<AnotherClass>()
{
new AnotherClass() {ID = 1, AnotherValue = 15, Value = 13},
new AnotherClass() {ID = 2, AnotherValue = 5, Value = 13}
};
var sortedList =
//here you're declaring variable a that will be like caret when you going through _assignmentControls
from a in _assignmentControls
join p in _priceLevels on a.ID equals p.ID
orderby p.AnotherValue
select a;
foreach (var someCLass in sortedList)
{
Console.WriteLine(someCLass.Name);
}
}
结果:
another test
test
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.