首页 > 其他分享 >Entity Framework教程-LINQ查询(LINQ for Queries and Projections)

Entity Framework教程-LINQ查询(LINQ for Queries and Projections)

时间:2022-10-22 08:11:23浏览次数:62  
标签:db OperatingSysId LINQ 查询 Framework Projections context var new

更新记录
转载请注明出处:
2022年10月17日 发布。
2022年10月10日 从笔记迁移到博客。

懒加载与预加载

默认情况下,EF是懒加载的,能只取一行数据就只取一行

如果需要预先加载全部数据,可以使用.Include方法

var queryResult = from item in db.SomeEntity.Include('表名')
										select item;

适合场景:查询结果需要遍历使用,最好预先加载全部数据,而不是使用时一条一条的去查询加载

执行事务(transaction)

using (var db = new Northwind())
{
    using (IDbContextTransaction t = db.Database.BeginTransaction())
    {
        Console.WriteLine("Transaction isolation level: {0}",t.GetDbTransaction().IsolationLevel);
        var products = db.Products.Where(p => p.ProductName.StartsWith(name));
        db.Products.RemoveRange(products);
        int affected = db.SaveChanges();
        t.Commit();
        return affected;
    }
}

Entity Framework中LINQ常见错误的使用

预取结果,然后迭代筛选(Pre-fetching results, then iterating to filter)

先执行排序和筛选然后再执行ToList等转换操作

var people = db.Person.ToList().OrderByDescending(x => x.LastName);

对比

var result = db.Person.OrderByDescending(x => x.LastName).Take(10);

第一个查询,将取得所有的结果集并且取得所有结果集后,还要对所有结果集进排序

而第二个查询将查询转为T-SQL再数据库进行筛选,然后进行返回,效率要高的多

对所有的数据操作进行跟踪变化

对于只是进行查询的数据完全没有必要进行跟踪变化

对于存储过程、函数、视图一般也可以设置为不跟踪变化

可以使用.AsNoTracking()方法,告知EF 不进行跟踪

var query = db.Person.AsNoTracking().OrderByDescending(x => x.LastName);
var result = query.Take(10);

如果整个EF的操作都是查询操作,可以设置DbContext全局不进行跟踪

ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

正确的选择IEnumerable and IQueryable作为结果集类型

主要取决于如何处理查询语句

IEnumerable IQueryable
Initial Query Server side Server side
Filtering Client side Server side

IEnumerable对象需要在一开始就提取数据

这意味着在使用IEnumerable对象(如List时)将不进行延迟加载

IQueryable对象允许使用过滤器构建整个查询

然后在执行时只将所需的确切数据存入内存

多实体连接

内连接

内连接是默认的行为,直接使用即可

using(var context = new MachineContext()) {
    var machines = from m in context.Machine
                    join o in context.OperatingSys 
                    on m.OperatingSysId equals  o.OperatingSysId
                    where m.MachineTypeId == 1
                    select new { 
                                    MachineName = m.Name,
                                    Role = m.GeneralRole,
                                    OperatingSystem = o.Name 
                                };

}

左外连接

默认情况下就是左外连接,也可以使用LEFT OUTER JOIN关键字

右外连接

使用RIGHT OUTER JOIN关键字即可

交集连接

using (var context = new MachineContext()) {
    var crossJoin = from m in context.Machine
                    from mw in context.MachineWarranty
                    select new {
                        m, mw
                    };
}

分组

LINQ语法

var mli = (from m in context.Machine
            join o in context.OperatingSys
            on m.OperatingSysId equals o.OperatingSysId
            group new { m, o } by m.OperatingSysId into grouped
            select new { 
                grouped.Key,
                count = grouped.Select(x=>x.m.OperatingSysId).Count(),
                Name = grouped.Select(ma=>ma.o.Name)
            }
          );

方法语法

var mType = context.Machine
 .GroupBy(m => m.MachineTypeId)
 .Select(g => new { id = g.Key, count = g.Count() });

分页

var result = context.OperatingSys
                .Where(whereClause)  //条件筛选
                .OrderBy(i => i.OperatingSysId) //排序条件
                .Skip(pageIndex * pageSize)     //跳过条数
                .Take(pageSize)                 //取得条数
                .ToList();

标签:db,OperatingSysId,LINQ,查询,Framework,Projections,context,var,new
From: https://www.cnblogs.com/cqpanda/p/16797944.html

相关文章