C# 查询列表的最有效(最快)方式
我正在努力找出查询列表最有效的方法。我知道这里有很多例子,以前也有很多,但我对这一点非常陌生,我正在努力将一些概念应用到我的情况中C# 查询列表的最有效(最快)方式,c#,performance,dynamics-crm,C#,Performance,Dynamics Crm,我正在努力找出查询列表最有效的方法。我知道这里有很多例子,以前也有很多,但我对这一点非常陌生,我正在努力将一些概念应用到我的情况中 private static void KeepMatchesBasedOnRestrictions(ref List<Entity> matches, List<Entity> preFilteredShifts, List<Entity> locationalInformations) {
private static void KeepMatchesBasedOnRestrictions(ref List<Entity> matches,
List<Entity> preFilteredShifts, List<Entity> locationalInformations)
{
if (matches.Count == 0) return;
matches.RemoveAll(
(match) => ( GeographyHasRestriction(match, preFilteredShifts, locationalInformations) )
);
}
private static bool GeographyHasRestriction(Entity match, List<Entity> preFilteredShifts, List<Entity> locationalInformations)
{
EntityReference fw = match.GetAttributeValue<EntityReference>("crm_fw");
Entity shift = preFilteredShifts.Single<Entity>(
a => match.GetAttributeValue<EntityReference>("crm_shift").Id == a.Id
);
EntityReference trust = shift.GetAttributeValue<EntityReference>("crm_trust");
EntityReference location = shift.GetAttributeValue<EntityReference>("crm_location");
EntityReference ward = shift.GetAttributeValue<EntityReference>("crm_ward");
Dictionary<Guid, Entity> locInfoRecs = locationalInformations.ToDictionary(p => p.Id);
var locationalInformationQuery = from loc in locationalInformations
where (
(
loc.GetAttributeValue<EntityReference>("crm_fw").Id == fw.Id
&& !loc.Contains("crm_trust")
&& !loc.Contains("crm_location")
&& !loc.Contains("crm_ward")
)
||
(
loc.GetAttributeValue<EntityReference>("crm_fw").Id == fw.Id
&& loc.GetAttributeValue<EntityReference>("crm_trust").Id == trust.Id
&& !loc.Contains("crm_location")
&& !loc.Contains("crm_ward")
)
||
(
loc.GetAttributeValue<EntityReference>("crm_fw").Id == fw.Id
&& loc.GetAttributeValue<EntityReference>("crm_trust").Id == trust.Id
&& loc.GetAttributeValue<EntityReference>("crm_location").Id == location.Id
&& !loc.Contains("crm_ward")
)
||
(
loc.GetAttributeValue<EntityReference>("crm_fw").Id == fw.Id
&& loc.GetAttributeValue<EntityReference>("crm_trust").Id == trust.Id
&& loc.GetAttributeValue<EntityReference>("crm_location").Id == location.Id
&& loc.GetAttributeValue<EntityReference>("crm_ward").Id == ward.Id
)
)
select loc;
foreach (Entity loc in locationalInformationQuery)
{
if (loc.GetAttributeValue<bool>("crm_hasrestriction"))
{
return true;
}
}
//return false;
}
private static void KeepMatchesBasedOnRestrictions(参考列表匹配,
列出预筛选的班次,列出位置信息)
{
if(matches.Count==0)返回;
RemoveAll(
(匹配)=>(地理图形限制(匹配、预过滤的班次、位置信息))
);
}
私有静态bool GeographyHasRestriction(实体匹配、列表预筛选移位、列表位置信息)
{
EntityReference fw=match.GetAttributeValue(“crm_fw”);
实体移位=预筛选移位。单个(
a=>match.GetAttributeValue(“crm_shift”).Id==a.Id
);
EntityReference trust=shift.GetAttributeValue(“crm_trust”);
EntityReference位置=shift.GetAttributeValue(“crm_位置”);
EntityReference ward=shift.GetAttributeValue(“crm_ward”);
字典locInfoRecs=locationalInformations.ToDictionary(p=>p.Id);
var locationalInformationQuery=来自locationalInformations中的loc
在哪里(
(
loc.GetAttributeValue(“crm_fw”).Id==fw.Id
&&!loc.Contains(“客户关系管理信托”)
&&!loc.Contains(“crm_位置”)
&&!loc.Contains(“crm_ward”)
)
||
(
loc.GetAttributeValue(“crm_fw”).Id==fw.Id
&&loc.GetAttributeValue(“crm_trust”).Id==trust.Id
&&!loc.Contains(“crm_位置”)
&&!loc.Contains(“crm_ward”)
)
||
(
loc.GetAttributeValue(“crm_fw”).Id==fw.Id
&&loc.GetAttributeValue(“crm_trust”).Id==trust.Id
&&loc.GetAttributeValue(“crm_位置”).Id==location.Id
&&!loc.Contains(“crm_ward”)
)
||
(
loc.GetAttributeValue(“crm_fw”).Id==fw.Id
&&loc.GetAttributeValue(“crm_trust”).Id==trust.Id
&&loc.GetAttributeValue(“crm_位置”).Id==location.Id
&&loc.GetAttributeValue(“crm_ward”).Id==ward.Id
)
)
选择loc;
foreach(locationalInformationQuery中的实体loc)
{
if(loc.GetAttributeValue(“crm_hasrestriction”))
{
返回true;
}
}
//返回false;
}
所以我认为我的问题是双重的
locationalInformationQuery
查询似乎运行得非常慢。。。我说的是每次迭代最多2秒的时间,这很可怕matches.RemoveAll()
的方法也有一些缺陷,因为列表存在性能问题locationalInformations
列表
转换为其他类型的容器,例如字典
,哈希集
或分类列表
,可以获得更好的性能。我的问题是,我不知道如何调整我的查询以利用这些更高效的容器
至于第二点,我也很想知道使用List.RemoveAll()
的替代方法。我可以灵活地在合理的范围内修改传入的容器类型,以确保这可能是可行的
对于任何用途的列表大小,match包含数千个项目,而预过滤移位
和位置信息
每个都包含>100000个项目
顺便说一句,我尝试使用Parallel.ForEach
而不是ForEach
,但实际上没有任何区别
编辑:为了澄清一些问题,我在记忆中做了所有这些。我已经完全填充了我的所有列表,所以不应该有任何额外的往返数据库。我相当肯定GetAttributeValue
不会进一步增加数据库开销
此外,这是一个调用Dynamics CRM Online的本地应用程序。代码-
foreach (Entity loc in locationalInformationQuery)
{
if (loc.GetAttributeValue<bool>("crm_hasrestriction"))
{
return true;
}
}
foreach(locationalInformationQuery中的实体loc)
{
if(loc.GetAttributeValue(“crm_hasrestriction”))
{
返回true;
}
}
这可能是缓慢的一个原因。您正在获取更多数据,然后在内存中枚举它们。您可以在获取之前直接执行检查,因此获取的数据更少,速度也更快。类似这样的事情-
return (from loc in locationalInformations
where ((
(
loc.GetAttributeValue<EntityReference>("crm_fw").Id == fw.Id
&& !loc.Contains("crm_trust")
&& !loc.Contains("crm_location")
&& !loc.Contains("crm_ward")
)
||
(
loc.GetAttributeValue<EntityReference>("crm_fw").Id == fw.Id
&& loc.GetAttributeValue<EntityReference>("crm_trust").Id == trust.Id
&& !loc.Contains("crm_location")
&& !loc.Contains("crm_ward")
)
||
(
loc.GetAttributeValue<EntityReference>("crm_fw").Id == fw.Id
&& loc.GetAttributeValue<EntityReference>("crm_trust").Id == trust.Id
&& loc.GetAttributeValue<EntityReference>("crm_location").Id == location.Id
&& !loc.Contains("crm_ward")
)
||
(
loc.GetAttributeValue<EntityReference>("crm_fw").Id == fw.Id
&& loc.GetAttributeValue<EntityReference>("crm_trust").Id == trust.Id
&& loc.GetAttributeValue<EntityReference>("crm_location").Id == location.Id
&& loc.GetAttributeValue<EntityReference>("crm_ward").Id == ward.Id
)
) && loc.GetAttributeValue<bool>("crm_hasrestriction")) // do the check before fetch in here
select loc).Any();
返回(从locationalInformations中的loc返回
在哪里((
(
private static bool GeographyHasRestrictionBySql(Entity match, List<Entity> preFilteredShifts, List<Entity> locationalInformations)
{
// Query here, and determine your boolean result to return
}