在开发过程中,经常需要从数据库查询数据,并将这些数据投影到不同的层级。LINQ to SQL 提供了一种方便的方式来执行这些操作。然而,如果不小心处理,可能会导致IQueryable泄露,这将影响性能。本文将介绍如何在不同层级使用LINQ to SQL进行数据投影,同时避免泄露IQueryable。
在LINQ to SQL中,通常使用如下方式进行数据查询和投影:
var query = from c in Cars
select new { c.carNo, c.eName };
这种方式只能在拥有“Cars”作为IQueryable的层级中使用。一旦将其返回为IList或IEnumerable,那么任何在其上的投影都将是LINQ to Entities,而不是LINQ to SQL,这意味着不会将投影发送到数据库。
使用LINQ to SQL进行投影的主要好处包括:
当在处理许多组合框和列表时,会感觉到“这帮助了很多”。
为了解决这个问题,可以通过动态编译代码来实现。将所需的字段列表发送到代码片段字符串,该字符串将被编译,然后调用编译后的函数以对任何实体进行投影。
public static IEnumerable<T> ProjectOn<T>(IQueryable query, string fieldsList) where T : class {
// 编译代码并执行
}
这种方法允许在不同的层级中使用LINQ to SQL进行投影,同时避免泄露IQueryable。
以下是一个示例解决方案,它包含多个项目,展示了如何在不同层级使用LINQ to SQL进行投影:
主要功能位于“LinqProjectionC.LinqProjection”类中:
public class LinqProjection {
static string codeIEnumerable = @"
using System;
using System.Collections.Generic;
using System.Linq;
namespace UserClasses {
public class RuntTimeClass {
public static IEnumerable<%TypeName%> anyFunction(IQueryable<%TypeName%> query) {
var enumerable = query.Select(c => new { %fieldsList% }).ToList();
var queryEntities = from c in enumerable
select new %TypeName%() {
%fieldsList%
};
return queryEntities.ToList();
}
}
}";
}