如何根据LINQ中的另一个字段动态选择字段?

时间:2020-04-20 08:39:42

标签: c# linq asp.net-core

我的项目中有 CloudCredential 表。在表中,我有4种类型(LIBVIRT,AWS,OPENSTACK,AZURE)(枚举),并且每种类型的字段大小不同。表结构看起来像

 {
        "id": 1,
        "cloudType": 2,
        "name": "CedricOpenstack",
        "organization": null,
        "organizationId": 1,
        "azureSubscriptionId": null,
        "azureClientId": null,
        "azureClientSecret": null,
        "azureTenantId": null,
        "openStackUser": "xxxx",
        "openStackPassword": "xxx",
        "openStackUrl": "xxx",
        "openStackProject": "xxx",
        "openStackDomain": "default",
        "openStackRegion": "RegionOne",
        "openStackPublicNetwork": "public",
        "openStackImportNetwork": false,
        "awsSecretAccessKey": null,
        "awsAccessKeyId": null,
        "awsDefaultRegion": null,
        "projects": []
    },

我有这样的方法。

         [HttpGet]
         public async Task<IActionResult> GetLibvirtCredentials([FromQuery]string 
          projectName)
         {
             var result = await (from project in _context.Projects
                 join cloud in _context.CloudCredentials on project.CloudCredentialId equals 
                 cloud.Id
                 where project.Name == projectName
                 select new
                 {
                     CloudName = cloud.Name,
                     CloudType = cloud.CloudType.ToString("G"),
                     OrganizationName = cloud.Organization.Name,
                     ProjectName = project.Name
                 }).ToListAsync();

             return Ok(result);
         }

问题是如果云类型= 2(OPENSTACK),我想根据云类型进行选择 还选择适合于此的字段(openStackUser,openStackProject等) 是否可以在选择中包含if语句。

P.S。 CloudType是动态的,它根据projectName进行更改,如果select内包含逻辑,则需要多个。

2 个答案:

答案 0 :(得分:0)

“您无法使用foreach内部选择” 。该查询将转换为SQL命令,因此您在查询中所做的一切都需要使用某些SQL命令来表示。

但是您可以查询整个项目,然后确定应该转发哪些数据

[HttpGet]
public async Task<IActionResult> GetLibvirtCredentials([FromQuery]string 
projectName)
{
    var result = await (from project in _context.Projects
        join cloud in _context.CloudCredentials on project.CloudCredentialId equals 
        cloud.Id
        where project.Name == projectName
        select new
        {
            CloudName = cloud.Name,
            CloudType = cloud.CloudType.ToString("G"),
            OrganizationName = cloud.Organization.Name,
            Project = project
        }).ToListAsync();

    var actualResult = result
        .Select(data => {
            switch (data.CloudType) {
                // deciding on the cloud type which fields should be forwareded
            }
        });

    return Ok(actualResult);
}

答案 1 :(得分:0)

您可以编写一个返回正确数据的函数。

您可以尝试类似的方法,但我尚未对其进行测试。

[HttpGet]
public async Task<IActionResult> GetLibvirtCredentials([FromQuery]string projectName)
{
    var result = await (from project in _context.Projects
                        join cloud in _context.CloudCredentials on project.CloudCredentialId equals
                        cloud.Id
                        where project.Name == projectName
                        select SelectData(project)).ToListAsync();

    return Ok(result);
}

private object SelectData(TypeOfProject project)
{
    switch (project.CloudType)
    {
        case 1:

            return new
            {
                CloudName = project.Name,
                CloudType = project.CloudType.ToString("G"),
                OrganizationName = project.Organization.Name,
                ProjectName = project.Name,
                OpenStackUser = project.openStackUser,
                OpenStackPassword = project.openStackPassword
            };


        case 2:
            return new
            {
                CloudName = project.Name,
                CloudType = project.CloudType.ToString("G"),
                OrganizationName = project.Organization.Name,
                ProjectName = project.Name,
                AzureSubscriptionId = project.azureSubscriptionId,
                AzureClientId = project.azureClientId
            };


        default:
            throw new NotSupportedException();
    }
}

我不赞成混合使用不同类型的东西。我将创建不同的函数来接收不同的对象类型。

相关问题