C# 如何根据特性列表的首次出现筛选对象列表?
假设我有以下代码:C# 如何根据特性列表的首次出现筛选对象列表?,c#,.net,linq,optimization,C#,.net,Linq,Optimization,假设我有以下代码: private class AccountRecord : IEquatable<AccountRecord>, IComparable<AccountRecord> { public Guid accountid { get; set; } public string accountnumber { get; set; } public string name { get; set; }
private class AccountRecord : IEquatable<AccountRecord>, IComparable<AccountRecord>
{
public Guid accountid { get; set; }
public string accountnumber { get; set; }
public string name { get; set; }
public Guid ownerid { get; set; }
public string owneridtype { get; set; }
public int number { get; set; }
public string companyname { get; set; }
public AccountRecord(Guid accountid, string accountnumber, string name, Guid ownerid, string owneridtype, int number, string companyname)
{
this.accountid = accountid;
this.accountnumber = accountnumber;
this.name = name;
this.ownerid = ownerid;
this.owneridtype = owneridtype;
this.number = number;
this.companyname = companyname;
}
public bool Equals(AccountRecord other)
{
if(this.name.Equals(other.name) && this.number == other.number){
return true;
}
else
{
return false;
}
}
public int CompareTo(AccountRecord other)
{
if (this.number > other.number)
{
return 1;
}
else if (this.number < other.number)
{
return -1;
}
else
{
return 0;
}
}
}
然后,我得到“companyname”属性的不同值列表
List<string> distinctCompanynames = accountRecords.Distinct(x => x.companyname).ToList<string>();
我想为每个不同的“companyname”属性获取具有最高“number”属性的AccountRecord对象列表。多亏了我所做的工作,我可以用嵌套的for循环来实现这一点,但是考虑到C拥有的所有工具,我的整个方法似乎不是最好的方法。这个列表最终会变得非常大,并且这个代码会频繁执行,所以我必须尽可能高效地执行。我怎样才能比我目前的方法更快/更好地完成这项工作
我目前的方法是:
列出会计记录
分类
反向重写AccountRecord的CompareTo方法可以删除此步骤。
在AccountRecords列表中列出不同的“companyname”值
硬编码一个嵌套的for循环,以对每个不同的“companyname”的AccountRecord的第一个存在执行某些操作。
我希望该方法是:
列出会计记录
获取新列表或将此列表筛选为AccountRecord对象的列表,每个不同的“companyname”属性都具有最高的“number”属性。
如果您有任何问题,请告诉我。我还没有测试过,但这应该可以:
from ac in accountRecords
group ac by ac.companyname into company
select new
{
Company = company.Key,
Number = company.OrderByDescending(g => g.number).FirstOrDefault()
}
更新:仔细阅读问题。它可以简化为:
List<AccountRecord> highestRecords =
(from ac in accountRecords
group ac by ac.companyname into company
select company.OrderByDescending(g => g.number).FirstOrDefault())
.ToList();
您是否打算在选择不同的公司时使用Distinct而不是Select?是的。我将对我的帖子进行编辑。那么,谢谢您注意到。GroupBy。我认为第一个问题应该是,您是否在实体框架中使用Linq,并且害怕通过频繁的数据库调用来缩小范围?如果是这样,您可以在上下文中对更复杂的方法进行“存在”和“包含”,然后再将其实现为适当的对象。如果没有,并且您已经有了对象或正在使用ADO.NET或其他数据检索,只需根据需要获取列表,然后从其他集合进行操作。例如:var数据=thing.ToList;变量分组=数据。选择操作。。。;var filter=data.Existsx=>x.Containssomething。。。;这种类型的筛选不是选项。数据源中不存在带有“number”或“companyname”的记录。我试图通过尽可能少地更改数据源体系结构来做到这一点。数据源是Microsoft Dynamics 365,因此不允许SQL查询。不过你说得对,在处理之前尽可能多地过滤数据是很理想的。我不熟悉from/group/select。我必须“使用”什么来编译它?@MichaelDrum Just System.Linq,您应该已经包含了它,谢谢您的编辑。我是Linq的新手,所以我需要更多的背景。我迫不及待地想看看它是否管用,管用!非常感谢您的解决方案@James。我特别喜欢它的简单易懂。
from ac in accountRecords
group ac by ac.companyname into company
select new
{
Company = company.Key,
Number = company.OrderByDescending(g => g.number).FirstOrDefault()
}
List<AccountRecord> highestRecords =
(from ac in accountRecords
group ac by ac.companyname into company
select company.OrderByDescending(g => g.number).FirstOrDefault())
.ToList();