繁体   English   中英

LINQ加入和orderby问题

[英]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/

更新:我只是再次仔细阅读了您的问题:

部分原因是我尝试比较/加入ArrayListIGenericListItem

有问题。 无法从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.IDint类型)而不是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM