c# - visual - linq測試




什麼是最困難或最誤解的LINQ的方面? (20)

背景:在接下來的一個月中,我將在C#的上下文中提供三個有關或至少包含LINQ的討論。 我想知道哪些主題值得給予相當多的關注,基於人們可能會覺得難以理解的內容,或者他們可能會誤認為什麼。 除了作為如何使用表達式樹(通常為IQueryable )遠程執行查詢的示例之外,我不會專門討論LINQ to SQL或實體框架。

那麼,你發現LINQ什麼難點? 你在誤解方面看到了什麼? 例子可能是以下任何一種,但請不要限制自己!

  • C#編譯器如何處理查詢表達式
  • Lambda表達式
  • 表達樹
  • 擴展方法
  • 匿名類型
  • IQueryable
  • 推遲與立即執行
  • 流與緩衝執行(例如,OrderBy被延遲但被緩衝)
  • 隱式鍵入局部變量
  • 讀取複雜的通用簽名(例如Enumerable.Join

編譯查詢

事實上,你不能鏈接IQueryable因為它們是方法調用(儘管沒有其他東西,但SQL可轉換!),它幾乎不可能解決它是mindboggling和創建一個DRY的巨大違反。 我需要我的IQueryable for ad-hoc,其中我沒有編譯查詢(我只為重度方案編譯查詢),但在編譯查詢中,我無法使用它們,而是需要再次編寫常規查詢語法。 現在,我在兩個地方做同樣的子查詢,如果事情發生變化,需要記住更新這兩個子查詢,等等。 一個噩夢。


IQueryable在第二種情況下同時接受Expression<Func<T1, T2, T3, ...>>Func<T1, T2, T3, ...> ,而不提示性能下降的提示。

這裡是代碼示例,它演示了我的意思:

[TestMethod]
public void QueryComplexityTest()
{
    var users = _dataContext.Users;

    Func<User, bool>                funcSelector =       q => q.UserName.StartsWith("Test");
    Expression<Func<User, bool>>    expressionSelector = q => q.UserName.StartsWith("Test");

    // Returns IEnumerable, and do filtering of data on client-side
    IQueryable<User> func = users.Where(funcSelector).AsQueryable();
    // Returns IQuerible and do filtering of data on server side
    // SELECT ... FROM [dbo].[User] AS [t0] WHERE [t0].[user_name] LIKE @p0
    IQueryable<User> exp = users.Where(expressionSelector);
}

group by依然讓我頭暈目眩。

任何關於延遲執行的混淆都應該能夠通過簡單的基於LINQ的代碼並在監視窗口中播放來解決。


var代表什麼時候執行查詢?

它是iQueryableiSingleResultiMultipleResult ,還是根據實現進行更改? 有一些關於使用(似乎是)動態類型與C#中的標準靜態類型的猜測。


事務(不使用TransactionScope)


在LINQ to SQL中,我經常看到人們不理解DataContext,如何使用它以及如何使用它。 太多的人沒有看到它是一個工作單元對象的DataContext,而不是持久對象。

我曾多次看到人們試圖單獨使用DataContext / session / etc,而不是為每個操作創造新的時間。

然後,在評估IQueryable之前就處理DataContext,但這更多的是人們不理解IQueryable而不是DataContext。

我看到很多混淆的另一個概念是查詢語法與表達式語法。 我將使用哪一個永遠是最容易的,經常堅持使用Expression Syntax。 許多人仍然沒有意識到他們最終會產生同樣的東西,畢竟Query被編譯成表達式。


如前所述,延遲加載和延遲執行

LINQ to Objects和LINQ to XML(IEnumerable)與LINQ to SQL(IQueryable)的不同之處在於,

如何在所有層中使用LINQ構建數據訪問層,業務層和表示層......並且是一個很好的例子。


嵌套循環的容易程度是我認為每個人都不了解的。

例如:

from outerloopitem in outerloopitems
from innerloopitem in outerloopitem.childitems
select outerloopitem, innerloopitem

延遲加載。


延遲執行


我不知道它是否符合誤解 - 但對我而言,這只是未知的。

我很高興了解DataLoadOptions以及我如何控制在進行特定查詢時連接哪些表。

請參閱此處了解更多信息: MSDN:DataLoadOptions


我仍然遇到了“let”命令(我從來沒有找到它的用處)和SelectMany(我曾用它,但我不確定我是否做得對)



我會說最被誤解的(或應該是不明白的?)LINQ的一個方面是IQueryable自定義的LINQ提供程序

我一直在使用LINQ一段時間,並且在IEnumerable世界中完全適應,並且可以解決LINQ的大部分問題。

但是當我開始查看並閱讀IQueryable,表達式和自定義linq提供程序時,它讓我頭腦轉動。 看看LINQ to SQL如何工作,如果你想看到一些非常複雜的邏輯。

我期待理解LINQ的這一方面......


我認為Lambda表達式可以解析表達式樹和匿名委託的事實,因此您可以將相同的聲明式lambda表達式傳遞給IEnumerable<T>擴展方法和IQueryable<T>擴展方法。


我認為LINQ被誤解的部分是它是一種語言擴展 ,而不是數據庫擴展或構造。

LINQ遠遠超過LINQ to SQL

現在我們大多數人都在使用LINQ收藏,我們永遠不會回去!

自從2.0中的泛型以及3.0中的匿名類型以來, LINQ是.NET最重要的特性。

而現在我們有了Lambda,我不能等待並行編程!


我認為,關於LINQ to SQL的第一個誤解是,為了有效地使用它,您仍然需要知道SQL。

關於Linq to Sql的另一個誤解是你仍然必須將數據庫安全性降低到荒謬的地步以使其工作。

第三點是,使用Linq to Sql和Dynamic類(意味著類定義在運行時創建)會導致大量的即時編譯。 這絕對會殺死性能。


正如大多數人所說,我認為最容易被誤解的部分是假設LINQ僅僅是T-SQL的替代品。 我認為自己是TSQL專家的經理不會讓我們在我們的項目中使用LINQ,甚至不願意MS發布這樣的事情!


理解Linq提供者之間的抽象何時洩漏。 有些東西可以在對像上工作,但不能在SQL上工作(例如.TakeWhile)。 一些方法可以被翻譯成SQL(ToUpper),而其他方法則不能。 一些技術在其他人更有效的SQL(不同的連接方法)中更有效。


花了很長時間才意識到許多LINQ擴展方法,例如Single()SingleOrDefault()等都有帶lambda表達式的重載。

你可以做 :

Single(x => x.id == id)

不需要說這個 - 一些糟糕的教程讓我養成了習慣

Where(x => x.id == id).Single()




c#-3.0