【问题标题】:C# Convert SQL query with Case statement to LINQC# 将带有 Case 语句的 SQL 查询转换为 LINQ
【发布时间】:2021-07-17 17:34:02
【问题描述】:

我在其中一个表中添加了一个新列,该列的结果取决于其他 2 个列的结果。我进行了更新,以便可以用信息填充现有行,但我还想将 case 语句转换为我的代码的 LINQ 查询。

UPDATE depotProjet.Projets
        SET IdPlateformeSecteur =
            CASE
                WHEN (IdPlateforme = 1 AND IdSecteur = 1) then 1
                WHEN (IdPlateforme = 1 AND IdSecteur = 2) then 2
                WHEN (IdPlateforme = 1 AND IdSecteur = 4) then 3
                WHEN (IdPlateforme = 3 AND IdSecteur = 1) then 4
                WHEN (IdPlateforme = 3 AND IdSecteur = 2) then 5
                WHEN (IdPlateforme = 3 AND IdSecteur = 4) then 6
                WHEN (IdPlateforme = 2 AND IdSecteur = 1) then 7
                WHEN (IdPlateforme = 2 AND IdSecteur = 2) then 8
                WHEN (IdPlateforme = 2 AND IdSecteur = 4) then 9
            
            End
        
        WHERE IdPlateformeSecteur is NULL;  

这就是我想出的:

if (projet.IdPlateforme == 1 && projet.IdSecteur == 1)
            {
                projet.IdPlateformeSecteur = 1;
            }
            else if (projet.IdPlateforme == 1 && projet.IdSecteur == 2)
            {
                projet.IdPlateformeSecteur = 2;
            }
            else if (projet.IdPlateforme == 1 && projet.IdSecteur == 4)
            {
                projet.IdPlateformeSecteur = 3;
            }
            else if (projet.IdPlateforme == 3 && projet.IdSecteur == 1)
            {
                projet.IdPlateformeSecteur = 4;
            }
            else if (projet.IdPlateforme == 3 && projet.IdSecteur == 2)
            {
                projet.IdPlateformeSecteur = 5;
            }
            else if (projet.IdPlateforme == 3 && projet.IdSecteur == 4)
            {
                projet.IdPlateformeSecteur = 6;
            }
            else if (projet.IdPlateforme == 2 && projet.IdSecteur == 1)
            {
                projet.IdPlateformeSecteur = 7;
            }
            else if (projet.IdPlateforme == 2 && projet.IdSecteur == 2)
            {
                projet.IdPlateformeSecteur = 8;
            }
            else if (projet.IdPlateforme == 2 && projet.IdSecteur == 4)
            {
                projet.IdPlateformeSecteur = 9;
            }

我的搜索给了我选择的例子,但我没有选择。它正在工作,但我想以正确的方式做到这一点。谢谢

【问题讨论】:

  • 到目前为止,您发布的只是一堆 If 语句。没有什么关于它的LINQ。您尝试过使用 LINQ 做什么?
  • LINQ 也主要用于选择数据,而不是更新数据,所以你确定你说的是你真正想要的吗?跨度>
  • 我知道我这样做的目的绝不是、塑造或形成 LINQ。我想知道在使用 LINQ 时是否有更雄辩的方式来做我所做的事情?对不起,如果我不清楚。
  • 不是没有看到 if 语句周围的相关代码来获取数据并“更新”它。
  • 对不起,英语不是我的母语,我不确定我理解正确。你还在寻找什么其他代码?

标签: c# sql linq linq-to-sql sql-to-linq-conversion


【解决方案1】:

我根据您的 depotProjet.Projet 模型和以下类做了一些假设,但应该足够接近以完成您想要的:

(工作 DotNet Fiddle 的链接:https://dotnetfiddle.net/i2RAx3

您可以使用Func<int, int, int> 传入IdPlatformeIdSecteurif 语句移出查询(以下使用递归模式匹配并且需要C# 8.0 或更高版本,否则您可以替换它与case 声明):

Func<int, int, int> SetIdPlatformeSecteur = (p, s) =>
    {
        int r = (p, s) switch
        {

            _ when p == 1 && s == 1 => 1,
            _ when p == 1 && s == 2 => 2,
            _ when p == 1 && s == 4 => 3,
            _ when p == 3 && s == 1 => 4,
            _ when p == 3 && s == 2 => 5,
            _ when p == 3 && s == 4 => 6,
            _ when p == 2 && s == 1 => 7,
            _ when p == 2 && s == 2 => 8,
            _ when p == 2 && s == 4 => 9,
            _ => throw new ArgumentException(message: "Id combination not recognized", paramName: $"{p} {s}")

        };

        return r;
    };

然后您可以查询您的项目数据库并返回一个匿名类型,其中包括您添加的项目模型中的字段IdPlateformeSecteur,如下所示:

new {
       x.Id, 
       x.IdPlateforme, 
       x.IdSecteur, 
       //...any other properties your model has and want returned
       IdPlateformeSecteur = SetIdPlatformeSecteur(x.IdPlateforme, x.IdSecteur)
    });

下面的完整 LINQPad 示例:

// Demo data to represent what would be in your databaseContext.Projects
List<Project> Projects = 
                        new List<Project> {
                                new Project { Id = 1, IdPlateforme = 1, IdSecteur = 1},
                                new Project { Id = 2, IdPlateforme = 1, IdSecteur = 2},
                                new Project { Id = 3, IdPlateforme = 1, IdSecteur = 4},
                                new Project { Id = 4, IdPlateforme = 3, IdSecteur = 1},
                                new Project { Id = 5, IdPlateforme = 3, IdSecteur = 2},
                                new Project { Id = 6, IdPlateforme = 3, IdSecteur = 4},
                                new Project { Id = 7, IdPlateforme = 2, IdSecteur = 1},
                                new Project { Id = 8, IdPlateforme = 2, IdSecteur = 2},
                                new Project { Id = 9, IdPlateforme = 2, IdSecteur = 4},
                            };

void Main()
{           
                        
    var results = Projects.Select(x => new {x.Id, x.IdPlateforme, x.IdSecteur, IdPlateformeSecteur = SetIdPlatformeSecteur(x.IdPlateforme, x.IdSecteur)});
    
    results.Dump();
}

Func<int, int, int> SetIdPlatformeSecteur = (p, s) =>
    {
        int r = (p, s) switch
        {

            _ when p == 1 && s == 1 => 1,
            _ when p == 1 && s == 2 => 2,
            _ when p == 1 && s == 4 => 3,
            _ when p == 3 && s == 1 => 4,
            _ when p == 3 && s == 2 => 5,
            _ when p == 3 && s == 4 => 6,
            _ when p == 2 && s == 1 => 7,
            _ when p == 2 && s == 2 => 8,
            _ when p == 2 && s == 4 => 9,
            _ => throw new ArgumentException(message: "Id combination not recognized", paramName: $"{p} {s}")

        };

        return r;
    };

public class Project
{
    public int Id { get; set; }
    public int IdPlateforme { get; set; }
    public int IdSecteur  { get; set; }
}

                                     

【讨论】:

    【解决方案2】:

    正如@gun2171 表示这里没有关于LINQ 的内容。

    为了清楚起见,您当前的代码似乎很容易阅读和维护。如果使用 C# 8,您可以使用 switch 表达式。思考eloquent,不如想想在几天、几个月或几年后回到代码,你和其他人是否理解这段代码?

    Mocked class

    public class ProjectItem
    {
        public int IdPlateforme { get; set; }
        public int IdSecteur { get; set; }
        public int IdPlateformeSecteur { get; set; }
    }
    

    Method 在名为 Operations.cs 的类中

    private static int SetIdSecteur(ProjectItem sender) => sender.IdPlateforme switch
        {
            1 when sender.IdSecteur == 1 => 1,
            1 when sender.IdSecteur == 2 => 2,
            1 when sender.IdSecteur == 4 => 3,
            3 when sender.IdSecteur == 1 => 4,
            3 when sender.IdSecteur == 2 => 5,
            3 when sender.IdSecteur == 4 => 6,
            2 when sender.IdSecteur == 1 => 7,
            2 when sender.IdSecteur == 2 => 8,
            2 when sender.IdSecteur == 4 => 9,
            _ => sender.IdPlateformeSecteur
        };
    

    用法

    var projet = new ProjectItem() { IdPlateforme = 1, IdPlateformeSecteur = 2};
    
    projet.IdSecteur = SetIdSecteur(projet);
    

    编辑

    碰巧与 Visual Studio 团队的一位 Microsoft PM 聊天,他们通过使用 C# 8 的元组提供了另一个想法。我对此不以为然,但提出这个替代解决方案似乎是谨慎的。

    public static int SetIdSecteur3(ProjectItem sender)
        => (sender.IdPlateforme, sender.IdSecteur) switch
        {
            (1, 1) => 1,
            (1, 2) => 2,
            (1, 4) => 3,
            (3, 1) => 4,
            (3, 2) => 5,
            (3, 4) => 6,
            (2, 1) => 7,
            (2, 2) => 8,
            (2, 4) => 9,
            _ => sender.IdPlateformeSecteur
        };
    

    【讨论】:

      猜你喜欢
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多