C# 如何使用可枚举类型从Linq创建结果集?

C# 如何使用可枚举类型从Linq创建结果集?,c#,linq,C#,Linq,结果集如下: ServiceName Ping Desc LogName BaseUrl EnvName Integrati

结果集如下:

ServiceName                                     Ping                                                         Desc                       LogName                                         BaseUrl                          EnvName         
IntegrationServices.BillingInstructionsService /IntegrationServices/BillingInstructionsService.svc/Rest/Ping BillingInstructionsService IntegrationServices.BillingInstructionsServices https://icrDev.xxx.com   Dev 
IntegrationServices.BillingInstructionsService /IntegrationServices/BillingInstructionsService.svc/Rest/Ping BillingInstructionsService IntegrationServices.BillingInstructionsServices https://IUTD01.xxx.com   DevUnitTest 
IntegrationServices.BillingInstructionsService /IntegrationServices/BillingInstructionsService.svc/Rest/Ping BillingInstructionsService IntegrationServices.BillingInstructionsServices https://ickd01.xxx.com    DevClock 
IntegrationServices.BillingInstructionsService /IntegrationServices/BillingInstructionsService.svc/Rest/Ping BillingInstructionsService IntegrationServices.BillingInstructionsServices https://icd01.xxx.com     DevConv 
是从下面的linq查询返回的,我的需要可以是筛选的(ServiceId)或未筛选的…:

var data = contextObj.ServiceMonitorMappings
            .Where(r => r.ServiceId == 33)
            .Select(x => new
            {
                ServiceName = x.Service.Name,
                Ping = x.Service.PingUrl,
                Desc = x.Service.Description,
                LogName = x.ServiceLoggingName.LoggingName,
                BaseUrl = x.ServiceBaseUrl.ServiceBaseUrl1,
                EnvName = x.ServiceEnvironment.Name
            });
ServiceMonitorMapping如下所示:

public partial class ServiceMonitorMapping
{
public int Id { get; set; }
public int ServiceEnvironmentId { get; set; }
public int ServiceId { get; set; }
public int ServiceLoggingNameId { get; set; }
public int ServiceBaseUrlId { get; set; }

public virtual Service Service { get; set; }
public virtual ServiceLoggingName ServiceLoggingName { get; set; }
public virtual ServiceBaseUrl ServiceBaseUrl { get; set; }
public virtual ServiceEnvironment ServiceEnvironment { get; set; }
}
var data = contextObj.ServiceMonitorMappings
            .Where(r => r.ServiceId == 33)
            .AsEnumerable()  //AsEnumerable after Where to apply filter on the DB query
            .GroupBy(x => 1) //data already filtered, only one group as a result
            .Select(x => new
            {
                ServiceName = x.First().Service.Name,
                Ping = x.First().Service.PingUrl,
                Desc = x.First().Service.Description,
                LogName = x.First().ServiceLoggingName.LoggingName,
                BaseUrl = x.Select(y => y.ServiceBaseUrl.ServiceBaseUrl1).ToList(), //ToList is optional
                EnvName = x.Select(y => y.ServiceEnvironment.Name).ToList() //ToList is optional
            });
我试图让BaseUrl和EnvName作为可枚举集合返回,这样我就不会有4条记录,而是1条记录,最后2列包含BaseUrl和EnvName的列表,但是我找不到方法来实现这一点。所以我只能用4张唱片,而不是1张。对我来说似乎并不理想

所以我的问题是,是否可以只返回一行,最后两列是一个集合,这样我就有了“项目列表”


任何帮助都将不胜感激

虽然托兰吉的答案相当好,但我相信这不是最简单的方法。您可以在分组后使用
选择
,以简化查询:

var data = contextObj.ServiceMonitorMappings
            .Where(r => r.ServiceId == 33)
            .Select(x => new
            {
                Key = new {ServiceName = x.Service.Name,
                           Ping = x.Service.PingUrl,
                           Desc = x.Service.Description,
                           LogName = x.ServiceLoggingName.LoggingName};
                BaseUrl = x.ServiceBaseUrl.ServiceBaseUrl1,
                EnvName = x.ServiceEnvironment.Name
            })
            .GroupBy(x => x.Key)
            .Select(g => new
            {
              ServiceName = g.Key.ServiceName,
              Ping = g.Key.Ping,
              Desc = g.Key.Desc,
              LogName = g.Key.LogName,
              BaseUrls = g.Select(x => x.BaseUrl).ToList(),
              EnvNames = g.Select(x => x.EnvName ).ToList();
            })
var data = contextObj.ServiceMonitorMappings
            .GroupBy(r => r.ServiceId)
            .Where(r => r.Key == 33)
            .Select(x => new
            {
                ServiceName = x.First().Service.Name,
                Ping = x.First().Service.PingUrl,
                Desc = x.First().Service.Description,
                LogName = x.First().ServiceLoggingName.LoggingName,
                BaseUrl = x.Select(y => y.ServiceBaseUrl.ServiceBaseUrl1).ToList(), //ToList is optional
                EnvName = x.Select(y => y.ServiceEnvironment.Name).ToList() //ToList is optional
            });
起初,我没有注意到这是一个通过LINQ到SQL的DB查询。为了使用这种方法,并且不因下载整个表而降低性能,您可以这样尝试:

public partial class ServiceMonitorMapping
{
public int Id { get; set; }
public int ServiceEnvironmentId { get; set; }
public int ServiceId { get; set; }
public int ServiceLoggingNameId { get; set; }
public int ServiceBaseUrlId { get; set; }

public virtual Service Service { get; set; }
public virtual ServiceLoggingName ServiceLoggingName { get; set; }
public virtual ServiceBaseUrl ServiceBaseUrl { get; set; }
public virtual ServiceEnvironment ServiceEnvironment { get; set; }
}
var data = contextObj.ServiceMonitorMappings
            .Where(r => r.ServiceId == 33)
            .AsEnumerable()  //AsEnumerable after Where to apply filter on the DB query
            .GroupBy(x => 1) //data already filtered, only one group as a result
            .Select(x => new
            {
                ServiceName = x.First().Service.Name,
                Ping = x.First().Service.PingUrl,
                Desc = x.First().Service.Description,
                LogName = x.First().ServiceLoggingName.LoggingName,
                BaseUrl = x.Select(y => y.ServiceBaseUrl.ServiceBaseUrl1).ToList(), //ToList is optional
                EnvName = x.Select(y => y.ServiceEnvironment.Name).ToList() //ToList is optional
            });

虽然托兰的答案相当好,但我相信这不是最简单的方法。您可以在分组后使用
选择
,以简化查询:

var data = contextObj.ServiceMonitorMappings
            .GroupBy(r => r.ServiceId)
            .Where(r => r.Key == 33)
            .Select(x => new
            {
                ServiceName = x.First().Service.Name,
                Ping = x.First().Service.PingUrl,
                Desc = x.First().Service.Description,
                LogName = x.First().ServiceLoggingName.LoggingName,
                BaseUrl = x.Select(y => y.ServiceBaseUrl.ServiceBaseUrl1).ToList(), //ToList is optional
                EnvName = x.Select(y => y.ServiceEnvironment.Name).ToList() //ToList is optional
            });
起初,我没有注意到这是一个通过LINQ到SQL的DB查询。为了使用这种方法,并且不因下载整个表而降低性能,您可以这样尝试:

public partial class ServiceMonitorMapping
{
public int Id { get; set; }
public int ServiceEnvironmentId { get; set; }
public int ServiceId { get; set; }
public int ServiceLoggingNameId { get; set; }
public int ServiceBaseUrlId { get; set; }

public virtual Service Service { get; set; }
public virtual ServiceLoggingName ServiceLoggingName { get; set; }
public virtual ServiceBaseUrl ServiceBaseUrl { get; set; }
public virtual ServiceEnvironment ServiceEnvironment { get; set; }
}
var data = contextObj.ServiceMonitorMappings
            .Where(r => r.ServiceId == 33)
            .AsEnumerable()  //AsEnumerable after Where to apply filter on the DB query
            .GroupBy(x => 1) //data already filtered, only one group as a result
            .Select(x => new
            {
                ServiceName = x.First().Service.Name,
                Ping = x.First().Service.PingUrl,
                Desc = x.First().Service.Description,
                LogName = x.First().ServiceLoggingName.LoggingName,
                BaseUrl = x.Select(y => y.ServiceBaseUrl.ServiceBaseUrl1).ToList(), //ToList is optional
                EnvName = x.Select(y => y.ServiceEnvironment.Name).ToList() //ToList is optional
            });

我希望你理解你的需要;我这样解决:

var query = contextObj.ServiceMonitorMappings
    .Where(r => r.ServiceId == 33)
    .Select(d => new { 
                 BaseUrl = d.ServiceBaseUrl.ServiceBaseUrl1, 
                 EnvName = d.ServiceEnvironment.Name})
    .Aggregate((d1, d2) =>
    new {
        BaseUrl = d1.BaseUrl + ", " + d2.BaseUrl,
        EnvName = d1.EnvName + ", " + d2.EnvName
    });
结果是:

BaseUrl
https://icrDev.xxx.com, https://IUTD01.xxx.com, https://ickd01.xxx.co, https://icd01.xxx.com 
EnvName 
Dev, DevUnitTest, DevClock, DevConv
编辑

我已更改查询以返回您所需的结果:

var query = contextObj.ServiceMonitorMappings
    .Where(r => r.ServiceId == 33)
    .Select(d => new { 
                 BaseUrl = d.ServiceBaseUrl.ServiceBaseUrl1, 
                 EnvName = d.ServiceEnvironment.Name})
        .Aggregate(
            //initialize the accumulator
            new { BaseUrl = new List<string>(), EnvName = new List<string>() }, 
            (acc, next) => //accumulator and nextItem
            {
                acc.BaseUrl.Add(next.BaseUrl);
                acc.EnvName.Add(next.EnvName);
                return acc;
            });
var query=contextObj.servicemonitorappings
.其中(r=>r.ServiceId==33)
.Select(d=>new{
BaseUrl=d.ServiceBaseUrl.ServiceBaseUrl1,
EnvName=d.ServiceEnvironment.Name})
.合计(
//初始化累加器
新建{BaseUrl=new List(),EnvName=new List()},
(acc,next)=>//累加器和nextItem
{
acc.BaseUrl.Add(next.BaseUrl);
acc.EnvName.Add(下一个.EnvName);
返回acc;
});

我希望您了解您的需求;我这样解决:

var query = contextObj.ServiceMonitorMappings
    .Where(r => r.ServiceId == 33)
    .Select(d => new { 
                 BaseUrl = d.ServiceBaseUrl.ServiceBaseUrl1, 
                 EnvName = d.ServiceEnvironment.Name})
    .Aggregate((d1, d2) =>
    new {
        BaseUrl = d1.BaseUrl + ", " + d2.BaseUrl,
        EnvName = d1.EnvName + ", " + d2.EnvName
    });
结果是:

BaseUrl
https://icrDev.xxx.com, https://IUTD01.xxx.com, https://ickd01.xxx.co, https://icd01.xxx.com 
EnvName 
Dev, DevUnitTest, DevClock, DevConv
编辑

我已更改查询以返回您所需的结果:

var query = contextObj.ServiceMonitorMappings
    .Where(r => r.ServiceId == 33)
    .Select(d => new { 
                 BaseUrl = d.ServiceBaseUrl.ServiceBaseUrl1, 
                 EnvName = d.ServiceEnvironment.Name})
        .Aggregate(
            //initialize the accumulator
            new { BaseUrl = new List<string>(), EnvName = new List<string>() }, 
            (acc, next) => //accumulator and nextItem
            {
                acc.BaseUrl.Add(next.BaseUrl);
                acc.EnvName.Add(next.EnvName);
                return acc;
            });
var query=contextObj.servicemonitorappings
.其中(r=>r.ServiceId==33)
.Select(d=>new{
BaseUrl=d.ServiceBaseUrl.ServiceBaseUrl1,
EnvName=d.ServiceEnvironment.Name})
.合计(
//初始化累加器
新建{BaseUrl=new List(),EnvName=new List()},
(acc,next)=>//累加器和nextItem
{
acc.BaseUrl.Add(next.BaseUrl);
acc.EnvName.Add(下一个.EnvName);
返回acc;
});

听起来你想要GroupBy,看一看,如果你想不出来,我会发布一个示例啊。。。我没有想过groupby。。。我来看看!非常感谢。听起来你想要GroupBy,看一看,如果你不明白,我会发布一个例子啊。。。我没有想过groupby。。。我来看看!非常感谢。真管用!我刚开始研究如何做到这一点。。。谢谢你的帮助!真管用!我刚开始研究如何做到这一点。。。谢谢你的帮助!只是测试了你的答案,我得到了一个错误:“方法第一”只能用作最终的查询操作。考虑在这个例子中使用方法“FrestRealStuty”,而不是“将第一个”改为“FrestRealStury”,然后生成另一个错误“AguMutExtExc:DbExpReloDeXixon需要一个带有集合结果类型的输入表达式。”这看起来像是“LINQ to SQL”的问题,请尝试在添加“AsEnumerable”类帮助之前调用或
ToList
添加“AsEnumerable”,但selectmany会创建IEnumerable not string的结果。所以每个字母在列表中都是它自己的元素。@Kixoka,看起来我太努力了。简单的
Select
does(正确答案)。另一方面,您可以尝试分析当前的解决方案中哪一个更快,因为LINQ to SQL在某些场景中可以很好地优化,而在其他场景中则根本无法优化-这还取决于数据的大小刚刚测试了您的答案,我得到了一个错误“方法“First”只能用作最终查询操作。考虑在这个实例中使用方法“FrestRealDebug”,而不是将“第一个”改为“FrestRealStury”,然后生成另一个错误“AgMutEntExert:DbExpExthSn束缚绑定需要一个带有集合结果类型的输入表达式”,这看起来像“LINQtoSQL”问题。“尝试在添加'AsEnumerable'类帮助之前调用或
ToList
,但selectmany会创建IEnumerable而不是string的结果。所以每个字母在列表中都是它自己的元素。@Kixoka,看起来我太努力了。简单的
Select
does(正确答案)。另一方面,您可以尝试分析当前的解决方案中哪些更快,因为LINQ to SQL在某些场景中可以很好地优化,而在其他场景中则完全没有——这还取决于数据的大小,这不是我所需要的,但我喜欢您的做法。谢谢大家!@Kixoka:现在我的查询返回一条记录和两个列表:)这不是我所需要的,但我喜欢你这样做。谢谢大家!@Kixoka:现在我的查询返回一条记录和两个列表:)