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# 有序清晰_C#_Linq_Sql Order By_Distinct - Fatal编程技术网

C# 有序清晰

C# 有序清晰,c#,linq,sql-order-by,distinct,C#,Linq,Sql Order By,Distinct,我有以下几点 IList<Project> projects = (from update in dbContext.TicketUpdates where update.TicketUpdatesEmployeeID == Profile.EmployeeID orderby update.TicketUpdatesEndDate descending select update.Ticket

我有以下几点

IList<Project> projects = (from update in dbContext.TicketUpdates
               where update.TicketUpdatesEmployeeID == Profile.EmployeeID
               orderby update.TicketUpdatesEndDate descending
               select update.Ticket.Project).Distinct().ToList();
IList projects=(来自dbContext.TicketUpdates中的更新)
其中update.TicketUpdatesEmployeeID==Profile.EmployeeID
orderby update.TicketUpdatesEndDate降序
选择update.Ticket.Project).Distinct().ToList();

我知道
Distinct()
不能保证顺序,但我无法在以后对其重新排序,因为投影丢失了我用于排序的字段。我如何解决这个问题?

使用GroupBy的新解决方案
更新: 实际上,有一个更简单的解决方案:

IList<Project> projects = (from update in dbContext.TicketUpdates where update.TicketUpdatesEmployeeID == Profile.EmployeeID)
    .GroupBy(tu=>tu.Ticket.Project)
    .Select(group=>group.First())
    .OrderByDescending(tu=>tu.TicketUpdatesEndDate)
    .Select(tu=>tu.Ticket.Project)
    .ToList();
IList projects=(来自dbContext.TicketUpdates中的更新,其中update.TicketUpdatesEmployeeID==Profile.EmployeeID)
.GroupBy(tu=>tu.Ticket.Project)
.Select(group=>group.First())
.OrderByDescending(tu=>tu.TicketUpdatesEndDate)
.Select(tu=>tu.Ticket.Project)
.ToList();
(我刚刚看到,当我写这篇文章时,其他人也给出了类似的答案)


使用自定义IEqualityComparer的旧解决方案(我不确定这是否适用于linq2sql)

因此,在投影数据之前,请使用自定义IEqualityComparer对TicketUpdates执行不同的操作

IEqualityComparer应将具有相同项目的所有TicketUpdates计算为相等。这样,具有相同项目的TicketUpdates将被丢弃

(请注意,您无法控制将丢弃具有相同项目的哪些TicketUpdates。因此,如果具有相同项目的这些TicketUpdates具有不同的结束日期,您将需要一个涉及GroupBy的解决方案

IList<Project> projects = (from update in dbContext.TicketUpdates where update.TicketUpdatesEmployeeID == Profile.EmployeeID)
    .Distinct(new ProjectComparer())
    .OrderByDescending(tu=>tu.TicketUpdatesEndDate)
    .Select(tu=>tu.Ticket.Project)
    .ToList();


// Your comparer should look somewhat like this 
// (untested code! And I do not know all the details about your class structure)
class ProjectComparer : IEqualityComparer<TicketUpdates>
{
    // Products are equal if their names and product numbers are equal. 
    public bool Equals(TicketUpdates x, TicketUpdates y)
    {

        //Check whether the compared objects reference the same data. 
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null. 
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether projects are equal. 
        //(perhaps do a null check for Ticket!)
        return x.Ticket.Project== y.Ticket.Project;
    }

    // If Equals() returns true for a pair of objects  
    // then GetHashCode() must return the same value for these objects. 

    public int GetHashCode(TicketUpdates x)
    {
        //Check whether the object is null 
        if (Object.ReferenceEquals(x, null)) return 0;

        // null check for Ticket and Project?
        return x.Ticket.Project.GetHashCode();
    }

}
IList projects=(来自dbContext.TicketUpdates中的更新,其中update.TicketUpdatesEmployeeID==Profile.EmployeeID)
.Distinct(新的ProjectComparer())
.OrderByDescending(tu=>tu.TicketUpdatesEndDate)
.Select(tu=>tu.Ticket.Project)
.ToList();
//你的比较器应该看起来像这样
//(未经测试的代码!我不知道关于类结构的所有细节)
类项目比较器:IEqualityComparer
{
//如果名称和产品编号相等,则产品相等。
公共布尔等于(票证日期x、票证日期y)
{
//检查比较对象是否引用相同的数据。
if(Object.ReferenceEquals(x,y))返回true;
//检查是否有任何比较对象为空。
if(Object.ReferenceEquals(x,null)| | Object.ReferenceEquals(y,null))
返回false;
//检查项目是否相等。
//(可能对票据执行空检查!)
返回x.Ticket.Project==y.Ticket.Project;
}
//对于一对对象,If Equals()返回true
//然后GetHashCode()必须为这些对象返回相同的值。
public int GetHashCode(ticketupx)
{
//检查对象是否为空
if(Object.ReferenceEquals(x,null))返回0;
//票证和项目的空检查?
返回x.Ticket.Project.GetHashCode();
}
}

我认为您最好的选择是发布流程以保留订单:

var projects = (from update in dbContext.TicketUpdates
           where update.TicketUpdatesEmployeeID == Profile.EmployeeID
           orderby update.TicketUpdatesEndDate descending
           select update.Ticket.Project);
var seen = new HashSet<Project>();
foreach (var project in projects)
{
    if (seen.Add(project))
    {
        // A distinct project
    }
}

通过跨
uu.Ticket.Project
使用
GroupBy
,每个更新都将按其关联的项目分组。如果您有10个项目和30个更新分布在其中,则在该阶段的输出中将有10个组(每个项目一个)。接下来,我们将按组的最新结束日期排序,这将保留您需要的降序我们正在查找。最后,我们从每个
i分组
项目中选择键。

您可以使用GroupBy运算符获取唯一记录,然后对新记录集执行排序

var projectList = dbContext.TicketUpdates.GroupBy(p => p.TicketUpdatesEmployeeId)
                    .Where( r => r.TicketUpdatesEmployeeId == Profile.EmployeeId)
                    .Select(r => r.First())
                    .OrderByDesc(q => q.TicketUpdatesEndDate)
                    .Select(n => n.First()).Ticket.Project;

我使用了
GroupBy
,因为我觉得它更合理。你介意解释一下
GroupBy
是如何工作的吗?我现在通过搜索了解了它,但当我问这个问题时,我不知道它的功能,我想这会帮助未来的观众理解。
var projectList = dbContext.TicketUpdates.GroupBy(p => p.TicketUpdatesEmployeeId)
                    .Where( r => r.TicketUpdatesEmployeeId == Profile.EmployeeId)
                    .Select(r => r.First())
                    .OrderByDesc(q => q.TicketUpdatesEndDate)
                    .Select(n => n.First()).Ticket.Project;