一、查詢
1.1 AsNoTracking() 非跟蹤查詢
在實體加上AsNoTracking()方法,返回的實體不會在System.Data.Entity.DbContext中進行緩存,因此能提高查詢性能(數據量大,性能提升3到4倍)。
注:
1、實體不進行跟蹤,所以修改實體後,進行SaveChanges()修改數據不會改變。
2、如果使用Select映射,不需要加AsNoTracking()。如:
Select(item=>new { item.Id,item.Name})
1.2 Any() 確定數據是否存在
使用Any(item=>item.Id==1)
查詢效率最高,FirstOrDefault次之,Count()最差(Any和Count相差幾百倍)。
1.3 AsNonUnicode()
查詢 (item=>item.Name="lee")
和(item=>item.Name==DbFunctions.AsNonUnicode("lee"))
區別在於生成的Sql語句前者Name=N'lee',後者Name='lee',N是將字符串作爲Unicode格式進行存儲。
因爲.Net字符串是Unicode格式,在上述SQL的Where子句中當一側有N型而另一側沒有N型時,此時會進行數據轉換,也就是說如果你在表中建立了索引此時會失效代替的是造成全表掃描。用 DbFunctions.AsNonUnicode 方法來告訴.Net將其作爲一個非Unicode來對待,此時生成的SQL語句兩側都沒有N型,就不會進行更多的數據轉換,也就是說不會造成更多的全表掃描。所以當有大量數據時如果不進行轉換會造成意想不到的結果。
因此在進行字符串查找或者比較時建議用AsNonUnicode()方法來提高查詢性能。
1.4 真假分頁
假:query.ToList().Skip((PageIndex - 1) * PageSize).Take(PageSize)
,把數據結果查詢出放到內存中,然後進行分頁。
真:query.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList()
,會把參數傳到數據庫,生成分頁Sql語句,在數據庫查詢。
1.5 按需返回列
Select(item => new { item.Id, item.CodeRuleId })
1.6 合理使用延遲加載
如果用不到導航屬性中的數據,那麼使用懶加載就行,不會加載不需要的數據到內存中。如果會在foreach中使用導航屬性中的數據,那麼最好是禁用懶加載,通過Include()方法,一次加載全部數據,防止在foreach多次和數據庫進行交互。
1.7 IQueryable和IEnumerable的區別
IQueryable返回的是查詢表達式,生成了SQL查詢語句但是還沒有與數據庫進行交互。
IEnumerable則是已經執行查詢數據庫的操作且數據保存在了內存中。所以在進行條件拼接的時候一定要在IQueryable類型後面追加Where條件語句,而不是等到ToList之後再開始寫條件。
錯誤:
db.Person.ToList().Where(item => item.Id == 1)
正確:
db.Person.Where(item => item.Id == 1).ToList()
二、排序
2.1 多字段組合排序
錯誤:.OrderBy(item=>item.Id).OrderBy(item=>itme.Name)
,生成Sql語句是Order By Name ASC。
正確:.OrderBy(item=>item.Id).ThenBy(item=>itme.Name)
,生成Sql語句是Order By Id ASC, Name ASC。
注:
1、另一種方法OrderBy(item=>new {item.Id,item.Name})
,生成Sql語句同上。
2、降序使用OrderByDescending、ThenByDescending。
三、數據操作
3.1 批量新增、修改和刪除
使用原生AddRange和RemoveRange時,會生成對應條數的Sql語句進行數據處理,可藉助第三方類庫實現一次性操作(並不生成多條Sql語句)。
第三方類庫:Entity Framework Plus是一個提高實體框架性能並克服MUST-HAVE功能限制的庫。
https://entityframework.net/zh-CN/tutorial/1000007/ef-plus