簡體   English   中英

如何將這個foreach循環轉換為Linq代碼?

[英]How to convert this foreach loop into Linq code?

我是Linq的新手,我想修改舊的c#代碼以使用Linq。 這段代碼的想法是選擇所有未設置的表和引用的字段PrimaryTable等於“myTable”


foreach (Table table in dbServer.Tables)
            {
                if (!table.IsSet)
                {
                    foreach (Reference refer in table.References)
                    {
                        if (refer.PrimaryTable == "myTable")
                        {
                            tables.Add(table);
                        }
                    }
                }
            }

在互聯網上挖掘后我得到了這段代碼


var q = from table in dbServer.Tables
                    let refers = from refer in table.References
                                 where refer.PrimaryTable == "myTable"
                                 select refer.ForeignTable
                    where refers.Contains(table.Name)
                    select table;

但它根本不起作用,我需要你的幫助才能使它有效。

提前致謝。

var tables = dbServer.Tables
    .Where(t => !t.IsSet)
    .SelectMany(t => t.References)
    .Where(r => r.PrimaryTable == "myTable")
    .ToList();

假設表是List<T>

編輯:正如評論所指出的,這與原作不同 - 看起來你真正想要的是這個:

var tables = dbServer.Tables
    .Where(t => !t.IsSet && t.References.Any(r => r.PrimaryTable == "myTable"))
    .ToList();

這將為您提供所有具有PrimaryTable為'myTable'的引用的表,該引用假定只有一個匹配的引用表。 否則,您可以多次添加相同的表。

只需要使用兩個來自

        var q = from table in dbServer.Tables
                where !table.IsSet
                from refer in table.References
                where refer.PrimaryTable == "myTable"
                select table;

編輯

實際上,我對這段代碼感到有點困惑。 你確定它正在做它的意圖嗎? 特別是,讓我失望的是你在table.References枚舉這一事實,但是當某個條件適用於某個特定Reference (即, refer.PrimaryTable == "myTable" ), 你要添加Tabletable )代替Referencerefer

這意味着如果一個Table有多個具有PrimaryTable == "myTable" Reference對象, PrimaryTable == "myTable" tables集合可能包含該Table多個副本。 這個對嗎?

我打算走出困境,並猜測你真正想要檢查的只是一個Table在其References集合中有任何帶有PrimaryTable == "myTable" Reference對象。 如果是這種情況,在tables.Add(table)之后的原始代碼中,我會簡單地添加break來避免重復。 (可能每個集合中只有一個Reference具有相同的PrimaryTable ,在這種情況下你會沒事;但是你仍然可以在這一點上停止枚舉。除非你想要重復。)

無論如何,Lee的代碼(以及我下面的內容)並沒有重復這種行為。 相反,它將Reference對象添加到列表中(因為最終的ToList調用在IEnumerable<Reference> )。

看來,如果我上面描述的是你所追求的行為,你可能想要這樣做:

var tables = dbServer.Tables
    .Where(table => !table.IsSet)
    .Where(
        table => table.References.Any(refer => refer.PrimaryTable == "myTable")
    ).ToList();

原始答案

我將擴展Lee的答案。 讓我們逐行分析。

// 1. enumerating over a collection
foreach (Table table in dbServer.Tables)
{
    // 2. checking a condition
    if (!table.IsSet)
    {
        // 3. enumerating over another collection
        foreach (Reference refer in table.References)
        {
            // 4. checking a condition
            if (refer.PrimaryTable == "myTable")
            {
                // 5. adding to a collection
                tables.Add(table);
            }
        }
    }
}

好。 所以我們得到了:

  1. 枚舉 - 簡單 - 這就是我們開始的地方
  2. 條件檢查 - 我們需要一個Where
  3. 枚舉另一個集合 - SelectMany
  4. 條件檢查- Where
  5. 添加 - 最有可能是ToList (取決於您想要的集合類型)

這是它的結果:

var tables = dbServer.Tables                         // step 1
    .Where(table => !table.IsSet)                    // step 2
    .SelectMany(table => table.References)           // step 3
    .Where(refer => refer.PrimaryTable == "myTable") // step 4
    .ToList();                                       // step 5

說得通?

tables.AddRange(dbServer.Tables
    .Where(t => !t.IsSet)
    .SelectMany(t => table.References)
        .Where(r => r.PrimaryTable == "myTable"));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM