我有以下映射函数:
private static Expression<Func<ActionComment, Domain.ActionComment>> MapActionComment =
actionComment => new Domain.ActionComment
{
Id = actionComment.Id,
Comment = actionComment.Comment,
};
private static Expression<Func<Action, Domain.Action>> MapAction =
action => new Domain.Domain
{
Id = action.Id,
Comments = action.ActionComments
.Select(ac => MapActionComment.Invoke(ac))
};
private static Expression<Func<Nc, Domain.Nc>> MapNc =
nc => new Domain.Nc
{
Id = nc.Id,
Actions = nc.Actions
.Select(a => MapAction.Invoke(a)),
};
以及以下 Linq-to-SQL 查询:
_ctx.NCs
.Where(n => n.Id == id)
.Select(MapNc)
.SingleOrDefault();
生成的 SQL 语句为:
SELECT [t0].[Id], -- columns
(SELECT COUNT(*)
FROM [dbo].[Actions] AS [t2]
WHERE [t2].[NCId] = [t0].[Id]
) AS [value]
FROM [dbo].[NCs] AS [t0]
LEFT OUTER JOIN [dbo].[Actions] AS [t1] ON [t1].[NCId] = [t0].[Id]
WHERE [t0].[Id] = @p0
ORDER BY [t0].[Id], [t1].[Id]
问题是 Action 对象的 Comments 集合不会加载其内容(它被推迟到集合的实际使用时)。
有什么方法可以强制 Linq-to-SQL 生成ONE 单个语句来获取 Ncs、Actions 和 ActionComments?
请您参考如下方法:
您应该查看通过 Linq2Sql 进行预加载。例如,请参阅此博客: http://www.lowendahl.net/showShout.aspx?id=190
貌似有点问题,不过一般情况下应该可以用。
实际上,如果可能的话,我会建议转向 EntityFramework。现在 LINQ2SQL 是一项遗留技术。特别是,EF 通过使用简单的 Include() 方法对预先加载提供了很好的支持,如下所示:
_ctx.NCs
.Where(n => n.Id == id)
.Select(MapNc)
.Include(nc => nc.Comments) //EF to eager load relation
.Include(nc => nc.Actions) //EF to eager load relation
.SingleOrDefault();
