1.定义
EF Core是微软的现代ORM,功能全面,支持多种数据库,适合复杂的数据模型和需要迁移的场景。LINQ to SQL较老,仅支持SQL Server,适合遗留项目。Dapper是轻量级的微ORM,性能高,适合需要直接控制SQL的场景。
EF Core开发效率高,但性能可能不如Dapper;Dapper性能好,但需要手写SQL,维护成本可能高;LINQ to SQL已经过时,但维护旧项目可能还需要用到。
都基于ADO.NET,支持LINQ查询(除了Dapper的部分情况),EF Core具有跨平台特性,而LINQ to SQL仅限于.NET Framework。
2. 基础查询示例
EF Core
var users = await dbContext.Users
.Where(u => u.Age > 18)
.OrderBy(u => u.Name)
.ToListAsync();
LINQ to SQL
var users = from u in db.Users
where u.Age > 18
orderby u.Name
select u;
Dapper
var users = connection.Query<User>(
"SELECT * FROM Users WHERE Age > @Age ORDER BY Name",
new { Age = 18 }
);
3.性能优化
针对于数据量较大的查询 往往EF CORE和Linq 并不适用 会出现查询超时 加载不出来的情况
从性能角度分析,Dapper通常比LINQ to SQL或Entity Framework等ORM框架更高效
性能优化建议
1.混合使用策略:
在实际项目中可以组合使用:
// 关键路径使用Dapper
var criticalData = connection.Query<...>(optimizedSql);
// 复杂业务使用EF Core
var complexData = dbContext.Orders
.Include(o => o.Items)
.Where(...)
.ToList();
// 遗留模块保持LINQ to SQL
var legacyData = (from p in legacyDb.Products select p).ToList();
2.对LINQ优化:
-
使用
AsNoTracking()
-
避免N+1查询
-
使用EF Core的
FromSqlRaw
执行优化SQL
3.对Dapper的优化:
-
使用参数化查询
-
利用多映射处理复杂关系
-
使用
Buffered=false
处理大数据集
典型的EF Core结构:
// 1. 定义仓储接口(可选)
public interface IRepository<T> where T : class
{
IQueryable<T> Query();
}
// 2. 实现仓储类
public class RelationshipDtlRepository : IRepository<RelationshipDtl>
{
private readonly AppDbContext _context;
public RelationshipDtlRepository(AppDbContext context)
{
_context = context;
}
public IQueryable<RelationshipDtl> Query()
{
return _context.RelationshipDtls.AsQueryable();
}
}
// 3. 使用仓储类查询(如代码片段所示)
var query = _relationshipDtlRepository
.Query()
.Where(_ => _.RelationshipNo == RelationshipEnum.ELocSRegion.ToString())
.Where(_ => _.LeftCode == input.LocNo)
.Where(_ => _.WarehouseNo == GetWareHouseNo());
-
LINQ 链式语法
.Where().Where().Where()
是典型的 EF Core 的IQueryable<T>
链式调用,符合 EF Core 的查询风格。 -
Lambda 表达式
_ => _.Property == value
是 EF Core 的标准 LINQ 表达式写法。 -
仓储模式
_relationshipDtlRepository
是典型的仓储类命名,常见于 EF Core 结合仓储模式的用法(如IRepository<T>
接口)。 -
强类型映射
通过RelationshipNo
、LeftCode
等属性直接映射到实体类字段,符合 EF Core 的 Code First 或 Database First 模式。
-
await (from outOrderTrayMaterial in _OutOrderTrayMaterialsRepository.Where(x => x.OutOrderNo == input.OutOrderNo && x.OutOrderTrayDtlNo == input.OutOrderTrayDtlNo) join material in _materialRepository on outOrderTrayMaterial.MaterialCode equals material.MaterialCode into materialTemp from materialInfo in materialTemp.DefaultIfEmpty() select new { outOrderTrayMaterial, materialInfo } ).ToListAsync();
这段代码使用的也是 Entity Framework Core (EF Core),
-
LINQ 查询语法
from ... join ... select
是标准的 LINQ 表达式语法,EF Core 完全支持这种写法。 -
异步方法
ToListAsync()
ToListAsync()
是 EF Core 的典型异步扩展方法,属于Microsoft.EntityFrameworkCore
命名空间。 -
仓储模式
_OutOrderTrayMaterialsRepository
和_materialRepository
是典型的仓储类(如IRepository<T>
),常见于 EF Core 的仓储模式实现。 -
导航属性缺失时的显式 JOIN
EF Core 中若未定义导航属性,需手动写join
,而其他 ORM(如 Dapper)通常不直接支持 LINQ 的join
语法。 -
为什么上述代码不是LINQ to SQL 的ORM形式
-
语法相似,但已过时且不支持
ToListAsync()
等异步方法。
-