C# EF & linq 常用操作


一、EF的左連接

在EF中,當在dbset使用join關聯多表查詢時,連接查詢的表如果沒有建立相應的外鍵關系時,EF生成的SQL語句是inner join(內聯),對於inner join,有所了解的同學都知道,很多時候這並不是我們的本意,實例如下:

var list = from o in context.CTMS_OD_ORDERS join d in context.CTMS_SUP_DOCTOR on o.OWNERDOCID equals d.USERID join e in context.CTMS_OD_ORDERSEVALUATION on o.ORDERID equals e.ORDERID select o;` 

EF生成了內連接(inner join)查詢,當兩個表的任一表的數據不匹配時,查詢結果就為空!實際上left join(左聯接)才是我們想要的,那么怎么樣才能生成left join查詢呢?其實只要我們如下改造,EF就能為我們生成left join(左聯接)查詢!

data = from o in context.CTMS_OD_ORDERS join d in context.CTMS_SUP_DOCTOR on o.OWNERDOCID equals d.USERID into dc from dci in dc.DefaultIfEmpty() join e in context.CTMS_OD_ORDERSEVALUATION on o.ORDERID equals e.ORDERID into ec from eci in ec.DefaultIfEmpty() where o.USERID == userID && (string.IsNullOrEmpty(type) || o.PRODUCTNAME.Contains(type)) select new ODOrders { BalanceStatus = o.BALANCESTATUS, ChannelOrderID = o.CHANNELORDERID, ChannelType = o.CHANNELTYPE, CreateDateTime = o.CREATEDATETIME, CreateUserID = o.CREATEUSERID, CreateUserName = o.CREATEUSERNAME, DocName = dci.DOCNAME, EvalutionStatus = string.IsNullOrEmpty(eci.ORDERID) ? "0" : "1", PayTime = o.PAYTIME, ProductCode = o.PRODUCTCODE, ProductName = o.PRODUCTNAME, ProductInstanceId = o.PRODUCTINSTANCEID, ProductID = o.PRODUCTID, OrderID = o.ORDERID, OrderCode = o.ORDERCODE, OrderStatus = o.ORDERSTATUS, OrderType=o.ORDERTYPE, TotalFee = o.TOTALFEE, UserID=o.USERID, UserName=o.USERNAME }; 

對比上下兩種寫法,可以看到在on表的后面我們加上了into xx,還有不要忘記,還需加上from xxx in xx.DefaultIfEmpty(),重要的就是最后的xx.DefaultIfEmpty(),它的作用是當連接的表為空時也會有一條空的數據,達到了left join的效果。

二、Linq

Union All/Union/Intersect操作

適用場景:對兩個集合的處理,例如追加、合並、取相同項、相交項等等。

Concat(連接)

說明:連接不同的集合,不會自動過濾相同項;延遲。

1.簡單形式:

var q = ( from c in db.Customers select c.Phone ).Concat( from c in db.Customersselect c.Fax ).Concat( from e in db.Employees select e.HomePhone );

語句描述:返回所有消費者和雇員的電話和傳真。

2.復合形式:

var q = ( from c in db.Customers select new { Name = c.CompanyName, c.Phone } ).Concat( from e in db.Employees select new { Name = e.FirstName + " " + e.LastName, Phone = e.HomePhone } );

語句描述:返回所有消費者和雇員的姓名和電話。

Union(合並)

說明:連接不同的集合,自動過濾相同項;延遲。即是將兩個集合進行合並操作,過濾相同的項。

var q = ( from c in db.Customers select c.Country ).Union( from e in db.Employeesselect e.Country );

語句描述:查詢顧客和職員所在的國家。

Intersect(相交)

說明:取相交項;延遲。即是獲取不同集合的相同項(交集)。即先遍歷第一個集合,找出所有唯一的元素,然后遍歷第二個集合,並將每個元素與前面找出的元素作對比,返回所有在兩個集合內都出現的元素。

var q = ( from c in db.Customers select c.Country ).Intersect( from e in db.Employeesselect e.Country );

語句描述:查詢顧客和職員同在的國家。

Except(與非)

說明:排除相交項;延遲。即是從某集合中刪除與另一個集合中相同的項。先遍歷第一個集合,找出所有唯一的元素,然后再遍歷第二個集合,返回第二個集合中所有未出現在前面所得元素集合中的元素。

var q = ( from c in db.Customers select c.Country ).Except( from e in db.Employeesselect e.Country );

語句描述:查詢顧客和職員不同的國家。

Top/Bottom操作

適用場景:適量的取出自己想要的數據,不是全部取出,這樣性能有所加強。

Take

說明:獲取集合的前n個元素;延遲。即只返回限定數量的結果集。

var q = ( from e in db.Employees orderby e.HireDate select e) .Take(5);

語句描述:查詢出最早5位雇用的雇員。

Skip

說明:跳過集合的前n個元素;延遲。即我們跳過給定的數目返回后面的結果集。

var q = ( from p in db.Products orderby p.UnitPrice descending select p) .Skip(10);

語句描述:查詢出第11個最貴產品后面的所有產品。

TakeWhile

說明:直到某一條件成立就停止獲取;延遲。即用其條件去依次判斷源序列中的元素,返回符合判斷條件的元素,該判斷操作將在返回false或源序列的末尾結束 。

SkipWhile

說明:直到某一條件成立就停止跳過;延遲。即用其條件去判斷源序列中的元素並且跳過第一個符合判斷條件的元素,一旦判斷返回false,接下來將不再進行判斷並返回剩下的所有元素。

Paging(分頁)操作

適用場景:結合Skip和Take就可實現對數據分頁操作。

var q = ( from c in db.Customers orderby c.ContactName select c) .Skip(50) .Take(10);

語句描述:跳過前50條記錄,取出接下來的10條記錄,形成乘積表在第6頁顯示。

var q = ( from p in db.Products where p.ProductID > 50 orderby p.ProductID select p) .Take(10);

SqlMethods操作

在LINQ to SQL語句中,為我們提供了SqlMethods操作,進一步為我們提供了方便,例如Like方法用於自定義通配表達式,Equals用於相比較是否相等。

Like

自定義的通配表達式。%表示零長度或任意長度的字符串;_表示一個字符;[]表示在某范圍區間的一個字符;[^]表示不在某范圍區間的一個字符。比如查詢消費者ID以“C”開頭的消費者。 

var q = from c in db.Customers where SqlMethods.Like(c.CustomerID, "C%") select c;

比如查詢消費者ID沒有“AXOXT”形式的消費者:

var q = from c in db.Customers where !SqlMethods.Like(c.CustomerID, "A_O_T") select c;

DateDiffDay

說明:在兩個變量之間比較。分別有:DateDiffDay、DateDiffHour、DateDiffMillisecond、DateDiffMinute、DateDiffMonth、DateDiffSecond、DateDiffYear 

var q = from o in db.Orders where SqlMethods .DateDiffDay(o.OrderDate, o.ShippedDate) < 10 select o;

語句描述:查詢所有10天之內的訂單。

Compiled Query操作

說明:在之前我們沒有好的方法對寫出的SQL語句進行編輯重新查詢,現在我們可以這樣做,看下面一個例子:

//1.創建compiled query NorthwindDataContext db = new NorthwindDataContext(); var fn =CompiledQuery.Compile( (NorthwindDataContext db2, string city) => from c indb2.Customers where c.City == city select c); //2.查詢城市為London的消費者,用LonCusts集合表示,這時可以用數據控件綁定 var LonCusts = fn(db, "London"); //3.查詢城市為Seattle的消費者var SeaCusts = fn(db, "Seattle");

其他:IQueryable,IEnumerable,List相互轉換

IQueryable,IEnumerable都可以通過ToList()轉換為類型。

其次

如果需要反向轉換,有兩個很好用的方法AsQueryable(),AsEnumerable(),可以順利將List轉換為IQueryable,IEnumerable。

 

List去重的表達式方法

users.Where((x,i)=>users.FindIndex(z=>z.name == x.name) == i) 

 

轉從:http://blog.sina.com.cn/s/blog_497dbcd10100a81s.html
 
        
轉從:https://www.cnblogs.com/shanshanlaichi/p/6666093.html
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM