【问题标题】:Convert SQL command to Linq Lambda function?将 SQL 命令转换为 Linq Lambda 函数?
【发布时间】:2020-03-31 22:11:36
【问题描述】:
SELECT     
    dbo.Projects.TaskMaster, dbo.Projects.Location, dbo.Photos.Photo
FROM
    dbo.Photos 
INNER JOIN
    dbo.Projects ON dbo.Photos.ProjectID = dbo.Projects.ProjectID
WHERE
    (dbo.Projects.IsTopProject = 1)

我需要使用 Linq Lambda 来实现这个 SQL 命令。

【问题讨论】:

  • 你的对象模型怎么样?
  • 我先用数据库。并通过以下方式获取数据:ProjectRepository blProject = new ProjectRepository(); IEnumerable<Project> projects = blProject.Select().Where(x => x.IsTopProject == true).ToList(); PhotoRepository blPhoto = new PhotoRepository(); IEnumerable<Photo> photos = blPhoto.Select();
  • @Aram 请edit 任何其他信息直接进入问题。

标签: c# sql-server asp.net-mvc linq asp.net-core


【解决方案1】:

这样的事情怎么样:

from photo in dbContext.Photos
join project in dbContext.Projects
on photo.ProjectID equals project.ProjectID
where project.IsTopProject == 1
select new { 
   photo.Photo, 
   project.TaskMaster,
   project.Location
};

如果你真的想使用 lambda,试试这个:

dbContent.Photos
   .Join(dbContext.Projects.Where(x => x.Project.IsTopProject == 1), 
         photo => photo.ProjectID,
         project => project.ProjectID,
         (photo, project) => new { 
            photo.Photo, 
            project.TaskMaster,
            project.Location 
         });

【讨论】:

  • 谢谢,但我需要 Lambda。在c#中可以使用Join方法
  • @Aram 就个人而言,我发现查询表达式更容易阅读。 Lambda 表达式可能会变得非常混乱,尤其是在使用多个 Join 时。但请随意使用任何你想要的东西。
【解决方案2】:
var result = dbo.Projects
    // you only want the top projects:
    .Where(project => project.IsTopProject == 1)

    .Join(dbo.Photos              // join the remaining Projects with Photos
    project => project.ProjectId, // from every project take the ProjectId,
    photo => photo.ProjectId,     // from every photo take the ProjectId,
    (project, photo) => new       // when they match make one new object
    {                             // containing the following properties:
         TaskMaster = project.TaskMaster,
         Location = project.Location,
         Photo = project.Photo,
    });

人们经常对“带有照片的热门项目”、“带有学生的学校”或“带有订单的客户”感兴趣。在这种情况下,GroupJoin 可能更有趣。

普通的内连接会给你以下序列:

Project  Photo
   A       3
   A       4
   B       2
   A       6
   C       1
   B       5

GroupJoin 将导致:

  • 带有照片 3、4、6 的项目 A
  • 项目 B 与照片 2、5
  • 项目 C 和照片 1
  • 项目 D 还没有照片。

除了感觉更自然之外,好处是,如果您有一个包含 1000 张照片的项目,您只需传输一次项目属性,而不是 1000 次。

为此,请考虑以下语句:

var result = dbo.Projects.Where(project => project.IsTopProject == 1)
    .GroupJoin(dbo.Photos                // GroupJoin the remaining Projects with Photos
    project => project.ProjectId,        // from every project take the ProjectId,
    photo => photo.ProjectId,            // from every photo take the ProjectId,
    (project, photosOfThisProject => new // from every project with all its matching
    {                                    // photos, make one new object
         TaskMaster = project.TaskMaster,
         Location = project.Location,

         Photos = photosOfThisProject.ToList(),

         // or if you only need some Photo properties:
         ProjectId = project.ProjectId,
         Photos = photosOfThisProject.Select( photo => new
         {
              // select the Photo properties that you plan to use
              Id = photo.Id,
              ...

              // not needed: you know the value:
              // ProjectId = photo.ProjectId,
         })
         .ToList()
    });

【讨论】:

    【解决方案3】:
    var query = database.Photos   
       .Join(database.Projects, 
          photos => photos.ProjectID,      
          project => project.ProjectID,   
          (photos, project) => new {Photos = photos, Projects = project}) 
       .Where(photosAndproject => photosAndproject.Projects.IsTopProject = 1);  
    

    【讨论】:

      【解决方案4】:
                  var result = await yourContext.Projects.Where(proj => proj.IsTopProject == true)
                         .Join(yourContext.Photos,
                               proj => proj.ProjectId,
                               photo => photo.ProjectID,
                               (proj,
                                photo) => new resultType
                                          {
                                              proj.TaskMaster,
                                              proj.Location,
                                              photo.Photo
                                          }).ToListAsync(cancellationToken); 
      

      【讨论】:

      • 谢谢,resultType 是Context.Projectsphoto.Photo 出错。为什么?
      • resultType 需要是匿名类型或相同的 DTO,这只是您数据的投影。类型项目没有照片属性。
      【解决方案5】:

      这个

      SELECT     dbo.Projects.TaskMaster, dbo.Projects.Location, dbo.Photos.Photo
      FROM         dbo.Photos INNER JOIN
                            dbo.Projects ON dbo.Photos.ProjectID = dbo.Projects.ProjectID
      WHERE     (dbo.Projects.IsTopProject = 1)
      

      应该是这样的

      var q = db.Photos()
                .Where( p => Projects.IsTopProject )
                .Select( p => new 
                    {
                     p.Project.TaskMaster, 
                     p.Project.Location, 
                     p.Photo
                    });
      

      在 EF 中,您应该使用 Navigation Properties 而不是 Join()。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多