Skip to main content
 首页 » 编程设计

c#之将 Linq-to-SQL 类映射到具有嵌套集合的域类

2024年01月13日28wuhuacong

我有以下映射函数:

 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();