LINQ 查询结果默认返回匿名对象,但实际开发中往往需要返回强类型的集合(如 List<StudentDto>),方便后续绑定到 UI、序列化输出或跨层传递。通过 Select 投影到具体类 + ToList() 物化即可实现。
基本写法
var q = from s in db.Student
select s;
var list = q.Select(m => new StudentDto()
{
id = m.id,
name = m.name,
age = m.age,
sex = (m.sex ?? false) ? "男" : "女"
}).ToList();Code language: JavaScript (javascript)
执行顺序:
Select定义投影逻辑 →ToList()触发查询执行 → 数据库返回结果后逐行映射到StudentDto。
生成的 SQL
SELECT [t0].[id], [t0].[name], [t0].[age], [t0].[sex]
FROM [dbo].[Student] AS [t0]Code language: CSS (css)
注意:
sex的? "男" : "女"转换在内存中完成(客户端求值),SQL 只查原始字段。
class Program
{
static void Main(string[] args)
{
using (var db = new DataClasses1DataContext())
{
var q = from s in db.Student
select s;
var list = q.Select(m => new StudentDto()
{
id = m.id,
name = m.name,
age = m.age,
sex = (m.sex ?? false) ? "男" : "女"
}).ToList();
// 后续可以绑定到 DataGridView / 返回 API / 序列化 JSON
foreach (var item in list)
{
Console.WriteLine($"{item.id} {item.name} {item.age} {item.sex}");
}
}
Console.ReadLine();
}
}
public class StudentDto
{
public int id { get; set; }
public string name { get; set; }
public int age { get; set; }
public string sex { get; set; }
}Code language: JavaScript (javascript)
常见变体
变体一:构造函数传参
public class StudentDto
{
public StudentDto(int id, string name, int age, string sex)
{
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
public int id { get; set; }
public string name { get; set; }
public int age { get; set; }
public string sex { get; set; }
}
// 调用
var list = q.Select(m => new StudentDto(m.id, m.name, m.age, (m.sex ?? false) ? "男" : "女")).ToList();Code language: JavaScript (javascript)
变体二:直接返回数据库实体类(不推荐,耦合高)
var list = q.ToList(); // 直接返回 List<Student>(DBML 实体类)Code language: PHP (php)
直接返回 DBML 实体类会暴露所有字段,且带 DataContext 状态追踪,跨层传递时不推荐。
变体三:分组后映射到 DTO
var list = (from s in db.Student
group s by s.sex into g
select new StudentGroupDto
{
Sex = g.Key ?? "未知",
Count = g.Count(),
Names = string.Join(",", g.Select(m => m.name))
}).ToList();Code language: JavaScript (javascript)
性能提示: Select 中只写需要的字段,生成的 SQL SELECT 只查对应列,减少数据传输量。不要先 select s 再 Select 映射——可以合并为一步:
var list = (from s in db.Student select new StudentDto { id = s.id, name = s.name, age = s.age, sex = (s.sex ?? false) ? “男” : “女” }).ToList();
Previous: 分组后多行合并为一行(string.Join)