如何在LINQ中编写查询和使用distinct和order by ?



您能告诉我如何用LINQ语法编写这个查询吗?

select distinct machine_id , sample_id  from results where custid = 18
order by sample_id

我尝试了这个,但不像查询它只显示machine_id在样本1中,但我需要为每个样本选择不同的machine_id

public ActionResult Indexs()
{
int UserId = Convert.ToInt32(Session["UserID"]);
var samples = _context.RESULTS.GroupBy(mach => mach.machine_id).Select( x=> x.FirstOrDefault()).Where(x=> x.custid == UserId).ToList();
return View(samples);
}

我找不到DistinctBy<>只有Distinct可用这个问题我都试过了,但都不适合我。

https://stackoverflow.com/questions/14321013/distinct-in-linq-based-on-only-one-field-of-the-table

我需要你的帮助,提前谢谢你

更新:

仍然解决方案没有像预期的那样工作,没有显示所有的数据,这是我使用的代码:

var samples = _context.RESULTS.GroupBy(mach => new { mach.machine_id, mach.sample_id }).Select(x=>x.FirstOrDefault()).OrderBy(n=> new { n.sample_id,n.program_id }).Where(x => x.custid == UserId).ToList();

这是我在RESULTS表中的示例,我需要选择:

user     sample no 1        machine_id 
1           1                     4
1           1                   2026
1           1                   2030
1           1                   2046
1           1                   2053
1           1                   2058
1           1                   2061
1           1                   2080 
1           1                   2081
1           1                   2083
1           1                   2084

但是使用这个命令它只显示4台机器:

2080年

2081年

2083年

2084年

和我认为groupby和firstdefault导致这个问题,请如何解决它然后像select语句一样从每个样例中选择不同的machine_id为什么在LINQ中做一个简单的查询很难?

这是VIEW代码,我不知道它是否有用:

@model IEnumerable<warehouse.Models.RESULT>
@{
ViewBag.Title = "Indexs";
Layout = "~/Views/Shared/_LayoutDashboard.cshtml";
}
<img style="margin-left:250px;" src="~/images/weblogo.png" />
<p style="margin-left:40px;">
<h3 style="margin-left:100px; font-family:Andalus;text-underline-position:below">
@Html.Label("Hospital Name :")
@Html.DisplayFor(model => Model.FirstOrDefault().sys_users.user_full_name)
</h3>

<table class="table table-bordered">
<tr style="background-color:hotpink">
<th>
@Html.DisplayNameFor(model => model.Program.name)
</th>
<th>
@Html.DisplayNameFor(model => model.sample.name)
</th>
<th>
@Html.DisplayNameFor(model => model.Machine.Machine_name)
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Program.name)
</td>
<td>
@Html.DisplayFor(modelItem => item.sample.name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Machine.Machine_name)
</td>
<td>
@Html.ActionLink("Enter", "Edit", new { id = item.sample_id, programId = item.program_id, custId = item.custid, machineId = item.machine_id }, new { @class = "btn btn-primary" }) |
@Html.ActionLink("Report", "Details", new { id = item.sample_id, programId = item.program_id, custId = item.custid }, new { @class = "btn btn-danger" }) |
@Html.ActionLink("Statistics", "Edit", "Statistics", new { programId = item.program_id, hospitalNo = item.custid }, new { @class = "btn btn-info" })
</td>
</tr>
}
</table>

下面是一个使用distinctBy

的例子
Obj obj0 = new() { Id = 1, SimpleId = 1, Name = "name1" };
Obj obj1 = new() { Id = 1, SimpleId = 1, Name = "name2" };
Obj obj2 = new() { Id = 1, SimpleId = 1, Name = "name1" };
Obj obj3 = new() { Id = 1, SimpleId = 1, Name = "name2" };
Obj obj4 = new() { Id = 1, SimpleId = 2, Name = "name4" };
Obj obj5 = new() { Id = 1, SimpleId = 2, Name = "name2" };
Obj obj6 = new() { Id = 1, SimpleId = 2, Name = "name3" };
List<Obj> list = new() { obj0,obj1,obj2, obj3 , obj4 , obj5 , obj6};
var result = list.OrderByDescending(o => o.Id).DistinctBy(p => new{p.SimpleId, p.Name}).OrderBy(o => o.Id);
Console.WriteLine( "liste count " + list.Count);
int n = 0;
foreach (Obj obj in result)
{
Console.WriteLine(++ n + " " +obj);
}
record Obj
{
public int Id { get; set; }
public int SimpleId { get; set;}
public string Name { get; set; }
}

结果显示

liste count 7
1 Obj { Id = 1, SimpleId = 1, Name = name1 }
2 Obj { Id = 1, SimpleId = 1, Name = name2 }
3 Obj { Id = 1, SimpleId = 2, Name = name4 }
4 Obj { Id = 1, SimpleId = 2, Name = name2 }
5 Obj { Id = 1, SimpleId = 2, Name = name3 }

你看到所有重复项都被删除了

您可能在查询中有输入错误或使用错误的属性。下面是得到正确的结果。我把订单分成两份。

using System;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Data;

namespace ConsoleApp2
{
class Program
{

static void Main(string[] args)
{
Context _context = new Context()
{
RESULTS = new List<RESULTS>()
{
new RESULTS() { user = 1, sample_id = 1, machine_id = 4 },
new RESULTS() { user = 1, sample_id = 1, machine_id = 2026 },
new RESULTS() { user = 1, sample_id = 1, machine_id = 2024 },
new RESULTS() { user = 1, sample_id = 1, machine_id = 2038 },
new RESULTS() { user = 1, sample_id = 1, machine_id = 2046 },
new RESULTS() { user = 1, sample_id = 1, machine_id = 2053 },
new RESULTS() { user = 1, sample_id = 1, machine_id = 2058 },
new RESULTS() { user = 1, sample_id = 1, machine_id = 2061 },
new RESULTS() { user = 1, sample_id = 1, machine_id = 2080 },
new RESULTS() { user = 1, sample_id = 1, machine_id = 2081 },
new RESULTS() { user = 1, sample_id = 1, machine_id = 2083 },
new RESULTS() { user = 1, sample_id = 1, machine_id = 2684 }
}
};
int UserId = 1;
var samples = _context.RESULTS.GroupBy(mach => new { mach.machine_id, mach.sample_id }).Select(x => x.FirstOrDefault()).OrderBy(n =>  n.sample_id ).ThenBy(x => x.machine_id).Where(x => x.user == UserId).ToList();
}
}
public class Context
{
public List<RESULTS> RESULTS { get; set; }
}
public class RESULTS
{
public int user { get; set; }
public int sample_id { get; set; }
public int machine_id { get; set; }
}

}

我发现你的问题帖子(就目前的情况而言)留下了一些有待解释的部分。

我的理解是显示的RESULTS选择

user_id  sample_id   machine_id
1        1           4
1        1           2026
1        1           2030
1        1           2046
1        1           2053
1        1           2058
1        1           2061
1        1           2080
1        1           2081
1        1           2083
1        1           2084

实际上是执行

时得到的选择

选择不同的user_id, sample_id, machine_id
from结果
,user_id = 1
order bysample_id

,而数据库中的RESULTS表可能包含更多的条目,而不是显示的11个。

这个假设正确吗?

(如果没有,请告知我,我将删除这个答案)

如果是这样,我认为RESULTS表中可能存在{ sample_id, machine_id }相等而user_id不同的表项。

例如,RESULTS可能包含两个条目,其中sample_id == 1machine_id == 4:
user_id  sample_id   machine_id
-------------------------------
2        1           4
1        1           4
...      ...         ...          // other entries

当按{ sample_id, machine_id }对这两个条目进行分组时,您将得到一个包含两个元素的分组:

Key:
{ 1, 4 }
Elements:
{ 2, 1, 4 },
{ 1, 1, 4 }

选择该分组中的第一个元素将会显示

{ 2, 1, 4 }

,仅仅是因为{ 2, 1, 4 }在表中{ 1, 1, 4 }之前出现了。我们基本上忽略了数据库表项{ 1, 1, 4 },甚至在到达.Where()语句之前。

现在,通过使用.Where()只获取与user_id == 1相关联的元素,元素{ 2, 1, 4 }将被排除,视为user_id == 2


因此我的建议是改变方法调用的顺序,以便.Where()在分组和选择第一个组元素之前使用。一个最小的例子:

var filteredResults = results
.Where(r => r.user_id == 1) // filtering before grouping
.GroupBy(r => new { r.machine_id, r.sample_id })
.Select(r => r.First());

这样做时,分组将只基于包含userId == 1的条目,因此,与user_id == 1相关的条目不会"丢失"。在选择每组中的第一个元素的阶段

这个小提琴可以帮助显示方法调用顺序的差异。

最新更新