Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ与组_concat-在一个字段中获取链接表结果_C#_Linq_Asp.net Core_Entity Framework Core - Fatal编程技术网

C# LINQ与组_concat-在一个字段中获取链接表结果

C# LINQ与组_concat-在一个字段中获取链接表结果,c#,linq,asp.net-core,entity-framework-core,C#,Linq,Asp.net Core,Entity Framework Core,早上好 我需要将以下SQLite查询传输到LINQ: "SELECT hostname, macaddress, uuid, group_concat(collection.collection_name) AS collection, daterequested, daterealized, requester, action_name AS action, done_name as done, comment FROM computerimport

早上好

我需要将以下SQLite查询传输到LINQ:

"SELECT hostname, macaddress, uuid, group_concat(collection.collection_name) AS collection, daterequested, daterealized, requester, action_name AS action, done_name as done, comment FROM computerimport 
                    LEFT OUTER JOIN action ON action.action_id = computerimport.action_id
                    LEFT OUTER JOIN done ON done.done_id = computerimport.done_id
                    LEFT OUTER JOIN computercollection ON computerimport.computer_id = computercollection.computer_id
                    LEFT OUTER JOIN collection ON computercollection.collection_id = collection.collection_id
                    GROUP BY computerimport.computer_id
                    ORDER BY daterequested;"
正如您所看到的,我有一些左外部联接,并且还使用一个组concat将一个表中的所有内容放在一个字段中,这样,当computercollection中存在一个设备两次时,我只得到一条记录。 我的LINQ查询如下所示

await (from ci in _context.ComputerImports
                      join re in _context.Results on ci.result_id equals re.result_id
                      join ac in _context.Actions on ci.action_id equals ac.action_id
                      join cc in _context.ComputerCollections on ci.computer_id equals cc.computer_id into gjcc
                         from subcc in gjcc.DefaultIfEmpty()
                      join co in _context.Collections on subcc.collection_id equals co.collection_id into gjco
                         from subco in gjco.DefaultIfEmpty()
                      select new OverviewViewModel
                                {
                                    computer_id = ci.computer_id,
                                    hostname = ci.hostname, 
                                    uuid = ci.uuid,
                                    collection_id = subcc.collection_id,
                                    collection_name = subco.collection_displayname,
                                    daterequested = ci.daterequested,
                                    daterealized = ci.daterealized,
                                    action_id = ci.action_id,
                                    action_name = ac.action_name,
                                    result_id = ci.result_id, 
                                    result_name = re.result_name,
                                    comment = ci.comment
                                }).OrderByDescending(e => e.daterequested).ToListAsync();
但我也尝试了使用字符串连接的group by:

await (from t in (from ci in _context.ComputerImports
                      join re in _context.Results on ci.result_id equals re.result_id
                      join ac in _context.Actions on ci.action_id equals ac.action_id
                      join cc in _context.ComputerCollections on ci.computer_id equals cc.computer_id into gjcc
                         from subcc in gjcc.DefaultIfEmpty()
                      join co in _context.Collections on subcc.collection_id equals co.collection_id into gjco
                         from subco in gjco.DefaultIfEmpty()
                      select new {ci.computer_id, ci.hostname, ci.uuid, subcc.collection_id, subco.collection_displayname, ci.daterequested, ci.daterealized, ci.action_id, ac.action_name, ci.result_id, re.result_name, ci.comment})
                    group t by new { t.computer_id, t.hostname, t.uuid, t.daterequested, t.daterealized, t.action_id, t.action_name, t.result_id, t.result_name, t.comment } into dg
                         select new OverviewViewModel
                                {
                                    computer_id = dg.Key.computer_id,
                                    hostname = dg.Key.hostname, 
                                    uuid = dg.Key.uuid,
                                    collection_id = dg.Key.result_id,
                                    collection_name = String.Join(",", dg.Select(d => d.collection_displayname).Distinct()),
                                    daterequested = dg.Key.daterequested,
                                    daterealized = dg.Key.daterealized,
                                    action_id = dg.Key.action_id,
                                    action_name = dg.Key.action_name,
                                    result_id = dg.Key.result_id, 
                                    result_name = dg.Key.result_name,
                                    comment = dg.Key.comment
                                }).OrderByDescending(e => e.daterequested).ToListAsync();
到目前为止没有运气。有没有办法让这个查询更简单?现在,与SQL语言相比,它感觉不太容易阅读


更新: 在使用MSSQL的Powershell中,它似乎也很简单:

$query = "SELECT hostname, uuid, STRING_AGG (TRIM(collection.collection_displayname), ' - ') as collection, daterequested, daterealized, requester, action_name AS action, result_name as result, comment 
                    FROM computerimport 
                    LEFT OUTER JOIN action ON action.action_id = computerimport.action_id
                    LEFT OUTER JOIN result ON result.result_id = computerimport.result_id
                    LEFT OUTER JOIN computercollection ON computerimport.computer_id = computercollection.computer_id
                    LEFT OUTER JOIN collection ON computercollection.collection_id = collection.collection_id
                    GROUP BY computerimport.computer_id, computerimport.hostname, computerimport.uuid, computerimport.daterequested, computerimport.requester, computerimport.daterealized, action_name, result_name, computerimport.comment
                    ORDER BY daterequested"

更新:

我接受了我的工作查询,并尝试从中创建一个新查询:

var result = ovm.GroupBy(cc => new {cc.computer_id, cc.hostname, cc.uuid, cc.daterequested, cc.daterealized, cc.action_id, cc.action_name, cc.result_id, cc.result_name, cc.comment})
                            .Select(dd => new { omputer_id = dd.Key.computer_id,
                                    hostname = dd.Key.hostname, 
                                    uuid = dd.Key.uuid,
                                    collection_name = String.Join(" - ", dd.Select(d => d.collection_name).Distinct()),
                                    daterequested = dd.Key.daterequested,
                                    daterealized = dd.Key.daterealized,
                                    action_id = dd.Key.action_id,
                                    action_name = dd.Key.action_name,
                                    result_id = dd.Key.result_id, 
                                    result_name = dd.Key.result_name,
                                    comment = dd.Key.comment});
不幸的是,结果是: 无法翻译Select(d=>d.collection_name)”。以可以翻译的形式重写查询,或者通过插入对AsEnumerable()、AsAsAsAsyncEnumerable()、ToList()或ToListSync()的调用显式切换到客户端计算。有关详细信息,请参阅。”


更新: 根据建议,我尝试使用如下所示的SQL语句:

因此,我使用所需字段创建了一个新类,并将其添加到模型生成器中:

public DbSet<OverviewQuery> OverviewQueries { get; set; }

modelBuilder.Entity<OverviewQuery>().ToView(nameof(OverviewQueries)).HasNoKey();
当我直接运行它时,我没有任何问题:

           string sqlquery = @"SELECT computerimport.action_id FROM computerimport LEFT OUTER JOIN action ON action.action_id = computerimport.action_id" ; 
_context.OverviewQueries.FromSqlRaw(sqlquery).ToList();

更新:

好的,模型必须具有与要传递的值完全相同的值,不能有更多:

string sqlquery = "SELECT computerimport.*, action.action_name, STRING_AGG(TRIM(collection.collection_name), ' - ') AS collection_name, STRING_AGG(TRIM(collection.collection_displayname), ' - ') AS collection_displayname, result.result_name " +
                            "FROM computerimport " + 
                            "LEFT OUTER JOIN action ON action.action_id = computerimport.action_id " +
                            "LEFT OUTER JOIN result ON result.result_id = computerimport.result_id " +
                            "LEFT OUTER JOIN computercollection ON computerimport.computer_id = computercollection.computer_id " +
                            "LEFT OUTER JOIN collection ON computercollection.collection_id = collection.collection_id " +
                            "GROUP BY computerimport.computer_id, computerimport.hostname, computerimport.uuid, computerimport.daterequested, computerimport.requester, computerimport.daterealized, computerimport.action_id, action_name, computerimport.result_id, result_name, computerimport.comment";


            var ovmraw = await _context.OverviewQueries.FromSqlRaw(sqlquery).ToListAsync();
概览查询

公共int计算机\u id{get;set;}

public string hostname {get; set;}
public string uuid {get; set;}
public Nullable<DateTime> daterequested {get; set;}  
public Nullable<DateTime> daterealized {get; set;}
public string requester {get; set;}
public int action_id {get; set;}
public int result_id {get; set;}
public string comment {get; set;}

// Values from other models
public string action_name {get; set;}
//public int? collection_id { get; set; }
public string collection_name {get; set;
public string collection_displayname {get; set;}
public string result_name {get; set;}
公共字符串主机名{get;set;}
公共字符串uuid{get;set;}
公共可为空的日期请求{get;set;}
公共可空日期{get;set;}
公共字符串请求程序{get;set;}
公共int操作\u id{get;set;}
public int result_id{get;set;}
公共字符串注释{get;set;}
//其他模型的值
公共字符串操作\u名称{get;set;}
//公共int?集合_id{get;set;}
公共字符串集合_name{get;set;
公共字符串集合_displayname{get;set;}
公共字符串结果_name{get;set;}

正如Panagiotis Kanavos所说,我必须/I切换到SQL,我让查询正常工作。此外,您还必须小心使用的模型。它必须具有与您的查询相同的确切属性。否则,它将失败并显示错误消息:

InvalidOperationException: The underlying reader doesn't have as many fields as expected.

LINQ不是SQL的替代品。不要这样使用它。它是一种在ORM之上使用的语言。ORM的工作是从关系而不是LINQ创建连接。而且,由于LINQ不是SQL,它没有特定于供应商的SQL扩展,如MySQL的GROUP_CONCAT或SQL Server的STRING_Agg。您为Powershell编写的不是Powershell,它只是SQL查询。但LINQ不是SQL。ORM通常不用于报告您发布的查询。聚合LINQ函数,如
Min
Max
等,只能帮助您实现这一点。创建视图并将实体映射到该视图更好,通常更快。我理解。创建视图是什么意思?每个表都有一个model和我有一个视图,我想在其中显示来自此模型的组合信息,除了连接问题外,该视图也在工作。我现在尝试使用SQLRAW,但这只允许我触摸一个表。
InvalidOperationException: The underlying reader doesn't have as many fields as expected.