麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

.NET深入實戰系列—LinqtoSql進階

2019-11-14 14:02:27
字體:
來源:轉載
供稿:網友

最近在寫代碼的過程中用到了Linq查詢,在查找資料的過程中發現網上的資料千奇百怪,于是自己整理了一些關于Linq中容易讓人困惑的地方。

本文全部代碼基于:UserInfo與Class兩個表,其中Class中的UserId與UserInfo中的Id對應

image

 本文唯一訪問地址:http://www.companysz.com/yubaolee/p/BestLinQQuery.html

linq聯合查詢

內聯查詢

內聯是一個實際使用頻率很高的查詢,它查詢兩個表共有的且都不為空的部分

 from user in UserInfo join c in Classes on user.Id equals c.UserId select new {     user.UserName,     user.Id,	 c.ClassName }

查詢結果

image

對應的SQL語句

SELECT [t0].[UserName], [t0].[Id], [t1].[ClassName]FROM [UserInfo] AS [t0]INNER JOIN [Class] AS [t1] ON [t0].[Id] = [t1].[UserId]

左聯查詢

左聯應該是聯合查詢中使用頻率最高的查詢。它以左表為準,進行聯合查詢。如果右表中不存在對應的結果,則置空。(注意:在Linq中是不存在右聯連的說法,因為右聯無非是把左邊的表移動到右邊,查詢的結果與左聯是一樣的)

from user in UserInfo  join c in Classes on user.Id equals c.UserId into temp  from c in temp.DefaultIfEmpty()  select new  {       user.UserName,       user.Id,       c.ClassName  }  

查詢結果

image

對應SQL語句

SELECT [t0].[UserName], [t0].[Id], [t1].[ClassName] AS [ClassName]FROM [UserInfo] AS [t0]LEFT OUTER JOIN [Class] AS [t1] ON [t0].[Id] = [t1].[UserId]

!注意一下左聯那個【temp】,它其實是一個IEnumerable集合。所以我們可以得到到左聯的另一種結果:

from user in UserInfojoin c in Classes on user.Id equals c.UserId into tempselect new{	user,	temp}

查詢結果(為了更明確表達集合,在Class表里特別加了一條記錄,所以class那邊共有3條)

image

對應SQL語句,與左聯的SQL基本一樣,但多了一個統計行數的列

SELECT t0.*, [t1].[Id] AS [Id2], t1.*, (    SELECT COUNT(*)    FROM [Class] AS [t2]    WHERE [t0].[Id] = [t2].[UserId]    ) AS [value]FROM [UserInfo] AS [t0]LEFT OUTER JOIN [Class] AS [t1] ON [t0].[Id] = [t1].[UserId]

全聯接

全聯連是得到兩個表的交叉結果(在SQL中稱為cross join),這種聯連方式得到的結果在沒有過濾條件的情況下,基本沒什么用。看看即可,代碼如下:

 from user in UserInfo from c in Classes select new {     user.UserName,     user.Id,	 c.ClassName }

查詢結果

image

對應SQL語句

SELECT [t0].[UserName], [t0].[Id], [t1].[ClassName]FROM [UserInfo] AS [t0], [Class] AS [t1]

合并(Union)

這種查詢其實也很少用,但在某些變態業務需求下會非常有用,注意查詢的結果。它是合并兩個表相同列數的結果,并且如果結果中有相同的行,那么只取一行記錄。

(	from userinfo in UserInfo	select new {	  Id = (System.Int32?)userinfo.Id,	  Name = userinfo.UserName	}).Union(	from c in Classes	  select new {	  Id = (System.Int32?)c.UserId,	  Name = c.ClassName	})

查詢結果

image

對應SQL語句

SELECT [t0].[Id] AS [value], [t0].[UserName]FROM [UserInfo] AS [t0]UNIONSELECT [t1].[UserId] AS [value], [t1].[ClassName]FROM [Class] AS [t1]

Linq 分組查詢

分組查詢(group by)也是我們在實際項目中一個常用的操作,查詢操作如下:

from c in Classesgroup c by c.UserId into tempselect temp

查詢結果

image

 

注意一下查詢結果,外層是一個我們常用的IQueryable<T>,里面是一個類似Dictionary的K-V集合。簡單點說Group返回的是一個集合的集合,因此輸出時需用雙重循環。

我們在使用它的結果時,應該這樣調用:

 var result = from c in _context.Classes                group c by c.UserId                into temp                select temp;            foreach (var c in result)            {                Console.WriteLine(c.Key);                foreach (var citem in c)                {                    Console.WriteLine(citem.ClassName);                }            }

實體增加字段處理

我在本文例子中的UserInfo實體類如下:

 public partial class UserInfo    {        public int Id { get; set; }        public string UserName { get; set; }        public string UserType { get; set; }        public int Money { get; set; }    }

現在我想在該實體中類中添加一個屬性。為了保持原實體類的純潔。我添加一個新的partial類:

public partial class UserInfo    {        /// <summary>        /// 測試擴展屬性        /// </summary>        public string UserExt        {            get { return UserName + ":" + UserType; }        }    }

然后我們用EF訪問一下,發現是可以訪問的:

image

但如果我們這樣使用時:

from user in _context.UserInfoesselect new{    user.Id,    user.UserExt};

會發現編譯是沒有問題的。但運行時會出現下面異常:

image

具體錯誤信息如下: The specified type member 'UserExt' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation PRoperties are supported.

即"UserExt"類型并不能被linq支持。因為在進入到foreach進行真正取數據之前。EF已經把linq轉成SQL語句,而UserExt會被轉成對應的數據庫字段。因為數據庫中并沒有該字段,所以會出現這個問題。解決的方法很簡單:

from user in _context.UserInfoes.ToList()select new  {      user.Id,      user.UserExt  }; 

即先執行ToList(),提前讓linq進行執行,生成UserInfo集合,這樣就可以正常訪問UserExt了。別看這個小小的改動。在多表聯查過濾字段的情況下,你會體會到無盡的妙處!

你可能會想到一個問題,如果我再加一個完整的屬性會出現什么情況?

 public partial class UserInfo    {        public string UserExt        {            get { return UserName + ":" + UserType; }        }        //新增一個完整的屬性        public string UserExt2 { get; set; }    }

上面的UserExt2是我們新加入的一個屬性,現在我們來執行一下查詢。我想真正去研究過Linq的人肯定知道結果了。

image

在Linq操作中實體中的屬性必須在配置映射時指定。我們的數據庫中當然沒有UserExt2這個字段,所以增加Ignore標識,或調用一下:

this.Ignore(t => t.UserExt2);

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 性 毛片| 一区二区三区日韩 | 国产影视 | 成人在线观看地址 | 特级黄一级播放 | 亚洲天堂字幕 | 成人毛片视频免费看 | 久久精品a一级国产免视看成人 | 久久综合婷婷 | 天天透天天狠天天爱综合97 | 性生活香蕉视频 | 成人在线影视 | 日韩字幕在线观看 | 99最新网址 | 性爱视频在线免费 | 久久精品亚洲精品国产欧美kt∨ | 偿还电影免费看 | 成人免费毛片一 | 国产女同玩人妖 | 国产精品视频亚洲 | 国产精品久久99精品毛片三a | 精品一区二区久久久久久按摩 | 蜜桃av网| 久久精品亚洲国产奇米99 | 91网站免费在线观看 | 国产午夜精品在线 | 福利免费视频 | 午夜丰满少妇高清毛片1000部 | 国产伦精品一区二区三区 | 日本黄色免费观看视频 | 国产三级在线观看a | 天使萌一区二区三区免费观看 | 色屁屁xxxxⅹ在线视频 | 一区二区三区欧美在线 | h色视频在线观看 | 亚洲片在线观看 | 国产精品剧情一区二区三区 | 中午字幕无线码一区2020 | 精品国产一区二区三区久久久 | lutube成人福利在线观看污 | 成人羞羞在线观看网站 |