简体   繁体   English

C# 将带有 Case 语句的 SQL 查询转换为 LINQ

[英]C# Convert SQL query with Case statement to LINQ

I added a new column in one of my table and the result of this column depends on the result of 2 other columns.我在我的一个表中添加了一个新列,该列的结果取决于其他 2 个列的结果。 I did a update so I can fill the existing rows with information but I would also like to transform the case statement into a LINQ query for my code.我进行了更新,因此我可以用信息填充现有行,但我还想将 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;  

this is what I'm coming up with:这就是我想出的:

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;
            }

my search are giving me example with select but I dont have a select.我的搜索给了我 select 的例子,但我没有 select。 It's working but I would like to do it the proper way.它正在工作,但我想以正确的方式做到这一点。 Thank you谢谢

As @gun2171 indicating there is nothing here in regards to LINQ .正如@gun2171 表明这里没有关于LINQ的内容。

For clarity of your current code seems easy enough to read and maintain.为了清楚起见,您当前的代码似乎很容易阅读和维护。 If working with C# 8 you could use a switch expression.如果使用 C# 8 您可以使用 switch 表达式。 Thinking eloquent , better to think of coming back to the code in days, months or years, do you and others understand this code?思考eloquent ,最好考虑几天、几个月或几年后回到代码,你和其他人是否理解这个代码?

Mocked class

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

Method in a class named Operations.cs名为 Operations.cs 的 class 中的Method

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
    };

Usage用法

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

projet.IdSecteur = SetIdSecteur(projet);

Edit编辑

Happened to be chatting with a Microsoft PM on the Visual Studio team and they provided another idea via tuples using C# 8. I can't take credit for this yet seems prudent to present this alternate solution.碰巧正在与 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
    };

I made some assumptions based off of your depotProjet.Projet model with the below class, but should be close enough to accomplish what you're wanting:我根据您的depotProjet.Projet model 和下面的 class 做了一些假设,但应该足够接近以完成您想要的:

(Link to working DotNet Fiddle: https://dotnetfiddle.net/i2RAx3 ) (链接到工作DotNet Fiddle: https://dotnetfiddle.net/i2RAx3

You can use a Func<int, int, int> to pass in the IdPlatforme and IdSecteur to move the if statement out of your query (the below uses recursive pattern matching and requires C# 8.0 or greater, otherwise you can replace it with case statement):您可以使用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;
    };

Then you can query your Projects database and return an anonymous type that includes the fields from your Project model you added IdPlateformeSecteur like this:然后您可以查询您的项目数据库并返回一个匿名类型,其中包括您添加的项目IdPlateformeSecteur中的字段,如下所示:

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

Full LINQPad example below:完整的 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; }
}

                                     

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM