簡體   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