EF操作与Linq写法记录、First、FirstOrDefault、Single、SingleOrDefault几个方法的区别

1、EF引入

  新建一个MVC项目之后,要引用EF框架,可以按照以下步骤进行:

  1),在Models中添加项目

  2),选择Entity Data Model,并重新填写名字

  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 表达式新增写法 :

  var data = db.Table.FirstOrDefault(tb => tb.id == id & tb.name == name);
  if (data == null)
  {
    var table = new Table();

    table.name = name;

    table.age = age;

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

 //Lambda 修改:

  var table = 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()

一个记录

  返回没有,默认值

多条异常

 
posted @ 2021-12-17 22:08  裳裳者华  阅读(706)  评论(0编辑  收藏  举报