1. 程式人生 > 其它 >EF操作與Linq寫法記錄、First、FirstOrDefault、Single、SingleOrDefault幾個方法的區別

EF操作與Linq寫法記錄、First、FirstOrDefault、Single、SingleOrDefault幾個方法的區別

1、EF引入

  新建一個MVC專案之後,要引用EF框架,可以按照以下步驟進行:

  1),在Models中新增專案

  2),選擇Entity DataModel,並重新填寫名字

  3),選擇程式碼優先之後,選擇連線的資料庫以及表,之後便生成,此時模型裡面的實體就相當於資料庫中的表了

2、Linq與一些lambda寫法

  1)、單表查詢:

using (var db = new DBModel())
{
    DepartmentList = (from n in db.output_Auth where n.badge == badge select n.department).Distinct().ToList<string>();
}
//from n(表別名) in table(表格) where n.id == id(條件) select n(查詢該表所有),然後後面可以選擇篩選的條件,比如.Distinct()\FirstOrDefault()\Sum()等
//select 中想要查詢具體的某個欄位,寫法為:select new {n.id, n.name, n.age}等,欄位想賦予別名,寫法為:select new {anotherID = n.id, anotherName = n.name}

注:幾個本專案中常用的方法:
1、OrderByDescending(n => n.id); //降序排列
2、FirstOrDefault(); //獲取查詢結果的第一行
3、ToList(); //將查詢結果列表化
4、Distinct(); //將查詢結果單一化,類似於SQL中的 distinct
5、Sum(n => n.id); //結果總和

剩下的在此次專案中未用到,將來使用到再總結。

  2)、多表查詢:

var time1 = (from a in Table_A join b in Table_B on a.id equals b.id where a.id == id & b.time == timeselect new { a.time, a.data}).ToList();
//在這裡和SQL的多表查詢語句寫法不太同,on後面的條件寫法為: a.x equals b.x

//補充1:無法直接在 Linq to SQL 的語句中將時間格式化,只能先查詢出來了,再在 Linq to Entity 中格式化時間
  即上面查詢語句 where b.time == time 中,b.time 不能寫成 b.time.ToString("yyyy-MM-dd") 之類的
  只能將查到的時間放在 time1 中,再對時間進行格式化,如下:
  var time2 = (from t in time1 where t.time.GetDataTimeFormats()[5].ToString() == nowDate select new{Data = t.data}).Sum(t => t.Data);
  GetDateTimeFormats()[5]時間格式:yyyy-MM-dd

//補充2:LinQ to SQL 中查詢的結果如果為0,則無法直接使用.Sum()求和,應該先將查詢的結果.ToList(),再進行第二步,在 LinQ to Entity 中進行求和。類似於上面的寫法,需要寫兩條語句。

  3)、插入與更新語句

using (var db = new DBModel())
{
   //插入之前先查詢有沒有該資料 var data = (from tb in db.Table where tb.id == id select tb).FirstOrDefault();
   //如果沒有該資料,則執行插入語句 if (data == null) { var table = new Table();
table.name = name;
    table.age = age;
//執行插入操作 db.Table.
Add(table);
    db.SaveChanges();
   }
   //如果當月有資料
    else
    {
        //Linq無法直接更新主鍵的資料,只能是先將此條資訊複製出來,把原來的那條資料刪除,再重新插入一條修改後的資料,若不是主鍵資料,則直接更新
        var tableNew = new Table();

        tableNew.name = name;
        tableNew.age = age;

        db.Table.Remove(data); //移除老資料
        db.Table.Add(tableNew); //新增新資料
        //執行更新操作
        db.SaveChanges();
    }
}      

//Lambda 表示式新增寫法 :

  vardata = db.Table.FirstOrDefault(tb => tb.id == id & tb.name == name);
  if (data ==null)
  {
    vartable =newTable();

    table.name = name;

    table.age = age;

    db.Table.Add(table);
    db.SaveChanges();
  }

 //Lambda 修改:

  vartable = db.Table.FirstOrDefault(tb => tb.id == id);
  table.name = name;
  table.age = age;
  db.SaveChanges();

  4)、刪除

//Lambda表示式寫法:
using (var db = new DBModel())
{
    var user = db.Table.FirstOrDefault(opAu => opAu.ID == userID);
    db.Table.Remove(user);
    db.SaveChanges();
}

//Linq寫法:
using (var db = new DBModel())
{
    var user = (from tb in db.Table select tb).FirstOrDefault();
    db.Table.Remove(tb);
    db.SaveChanges();
}

EF中使用Linq時First、FirstOrDefault、Single、SingleOrDefault幾個方法的區別

在使用EntityFramework開發時,.NET的System.Linq.Enumerable類為我們提供了許多Linq方法。

給大家分享一下關於First、FirstOrDefault、Single、SingleOrDefault幾個方法的區別例項及使用場景,首先是關於這幾個方法的定義:

First:返回序列中的第一條記錄,如果沒有記錄,則引發異常。

FirstOrDefault:返回序列中的第一條記錄,如果沒有記錄,則返回預設值。

Single:返回序列中的唯一記錄,如果沒有或返回多條記錄,則引發異常。

SingleOrDefault:返回序列中的唯一記錄;如果該序列為空,則返回預設值;如果該序列包含多個元素,則引發異常。

二、例項和用法

1、First與FirstOrDefault

◆ First返回序列中的第一條記錄,如果沒有記錄,則引發異常,示例程式碼如下:

static void Main(string[] args)
{
       string[] strName = { "Fred", "Gary", "William", "Charles" };
       string[] strNameEmpty = { };
       try
       {
           string tempName = strName.First();
           Console.WriteLine("First()第一種 返回序列中的第一條記錄。");
           Console.WriteLine("資訊為:{0}", tempName);

           //如果序列中沒有元素則會發生,InvalidOperationException 異常。 源序列為空。
           string tempNameEmpty = strNameEmpty.First();
       }
       catch (Exception ex)
       {
           Console.WriteLine("First()第二種 返回序列中沒有元素,引發異常。");
           Console.WriteLine("資訊為:{0}", ex.Message);
       }
}

結果如下圖所示:

◆ FirstOrDefault返回序列中的第一條記錄,如果序列中不包含任何記錄,則返回預設值(對於可以為null的物件,預設值為null,對於不能為null的物件,如int,預設值為0),示例程式碼如下:

static void Main(string[] args)
{
       string[] strName = { "Fred", "Fred", "William", "Charles" };
       string[] strNameEmpty = { };// string 型別的預設值是空
       string tempName = strName.FirstOrDefault();
       Console.WriteLine("FirstOrDefault()第一種 返回序列中的第一條記錄。");
       Console.WriteLine("資訊為:{0}", tempName);

       string tempNameEmpty = strNameEmpty.FirstOrDefault();
       Console.WriteLine("FirstOrDefault()第二種 如果序列中不包含任何記錄,則返回預設值。");
       Console.WriteLine("資訊為:{0}", tempNameEmpty);
}

結果如下圖所示:

2、Single與SingleOrDefault

◆Single返回序列中的唯一一條記錄,如果沒有或返回多條,則引發異常,示例程式碼如下:

static void Main(string[] args)
{
         string[] strName = { "Fred"};
         string[] strNameEmpty = { };
         try
         {
             string tempName = strName.Single();
             Console.WriteLine("Single()第一種 返回序列中的唯一一條記錄。");
             Console.WriteLine("資訊為:{0}", tempName);

             //沒有或返回多條,則引發異常。 string[] strNameEmpty = { "Fred","Crazy"};
             string tempNameEmpty = strNameEmpty.Single();
         }
         catch (Exception ex)
         {
             Console.WriteLine("Single()第二種 沒有或返回多條,則引發異常。");
             Console.WriteLine("資訊為:{0}", ex.Message);
         }
}

結果如下圖所示:

◆SingleOrDefault返回序列中滿足指定條件的唯一元素;如果這類元素不存在,則返回預設值;如果有多個元素滿足該條件,此方法將引發異常,示例程式碼如下:

static void Main(string[] args)
{
         string[] strName = { "Fred"};
         string[] strNameEmpty = { };
         string[] strEmpty = { "Fred", "Crazy" };
         try
         {
             string tempName = strName.SingleOrDefault();
             Console.WriteLine("SingleOrDefault()第一種 返回序列中的唯一記錄。");
             Console.WriteLine("資訊為:{0}", tempName);

             string tempNameEmpty = strNameEmpty.SingleOrDefault();
             Console.WriteLine("SingleOrDefault()第二種 如果該序列為空,則返回預設值。");
             Console.WriteLine("資訊為:{0}", tempNameEmpty);

             //序列包含多個元素,則引發異常 string[] strNameEmpty = { "Fred","Crazy"};
             string tempEmpty = strEmpty.SingleOrDefault();
         }
         catch (Exception ex)
         {
             Console.WriteLine("SingleOrDefault()第三種 如果該序列包含多個元素,則引發異常。");
             Console.WriteLine("資訊為:{0}", ex.Message);
         }
}

結果如下圖所示:

三、什麼時候用First、FristOrDefault、Single、SingleOrDefault?

1、當集合中只有一個元素時,可以使用Single

2、當集合中不包含任何元素但需要返回預設值時,可以使用SingleOrDefault。

3、當集合中包含多個元素想丟擲異常時,可以使用SingleSingleOrDefault。

4、無論集合中是否有元素,我們都想要返回一個記錄時,可以使用FirstFirstOrDefault。

5、當集合中不包含任何元素但需要返回預設值時,可以使用FirstOrDefault。

四、總結

FirstSingle的區別:前者是TOP(1)後者是TOP(2),後者如果查詢到兩條資料則丟擲異常。所以在必要的時候使用Single也不會比First慢多少。

FirstOrDefaultSingleOrDefault的效能比較:

FirstOrDefault通常在效能上會比SingleOrDefault表現得比優,因為FirstOrDefault是從集合開始位置查詢到第一個匹配的元素就返回,而SingleOrDefault會迭代集合中所有的元素。

助記:有OrDefault的方法會返回值(如果沒有符合條件的元素,則返回預設值),沒有OrDefault的方法會丟擲異常。

方法名

First()

一條記錄

返回沒有,則異常

FirstOrDefault()

一條記錄

返回沒有,預設值

Single()

一個記錄

返回沒有,則異常

多條異常

SingleOrDefault()

一個記錄

返回沒有,預設值

多條異常