我的代码目前看起来像:
foreach(var request in requestsList){
foreach(var myVar in request.anotherList){
if(myVar.hasPermissions()) {
//do something
}
}
}
requestsList
是List
的{{1}}。
Request
需要连接到数据库,因此我希望最小化对数据库的调用次数。我想将它移到内部myVar.hasPermissions()
循环之外,并且每个请求只进行一次调用。
我正在努力实现这样的目标:
foreach
我想要做的就是将foreach(var request in requestsList){
//check for permissions
boolean perm = myVar.hasPermissions(); //database call to check permissions
foreach(var myVar in request.anotherList){
if(perm) {
//do something
}
}
}
移到内部hasPermissions()
循环之外。
我面临的问题是我无法访问外部foreach
循环中的myVar
。迭代遍历列表的循环对我来说很难。
答案 0 :(得分:0)
如果hasPermission
相对静态,即您确定它不会在外循环的运行中发生变化,则可以在检查时缓存权限:
IDictionary<MyVarType,bool> checked = new IDictionary<MyVarType,bool>();
foreach(var request in requestsList){
foreach(var myVar in request.anotherList) {
bool permitted;
if (!checked.TryGetValue(myVar, out permitted)) {
permitted = myVar.hasPermissions();
checked.Add(myVar, permitted);
}
if(permitted) {
//do something
}
}
}
通过这种方式,您可以根据hasPermissions
的不同实例对myVar
进行一次调用;所有后续检查都来自checked
缓存。
答案 1 :(得分:0)
如果没有关于课程的更多细节,我们只能推测如何最好地解决问题。假设您的anotherList
包含类似用户列表的内容,您可以缓存检查结果,这样您就不会再次检查同一个用户。
您可以添加使用Lazy
的公共字段来缓存调用hasPermissions
的结果 - 您必须在构造函数中初始化它:
public class User {
public bool hasPermissions() { // check database for permissions
var ans = false; // ...
return ans;
}
public Lazy<bool> cachedPermissions;
public User() {
UncachePermissions();
}
public void UncachePermissions() => cachedPermissions = new Lazy<bool>(() => hasPermissions());
}
现在,您可以访问cachedPermissions
,而不是调用hasPermissions
:
foreach (var request in requestsList) {
foreach (var myVar in request.anotherList) {
if (myVar.cachedPermissions.Value) {
//do something
}
}
}
每个hasPermissions
对象只会调用和User
一次。如果单个数据库调用可能存在多个User
对象,则需要有关类和方法的更多详细信息。
我添加了UncachePermissions
方法来重置缓存,否则您可以使用可能导致问题的hasPermissions
的旧值。如果这可能是一个常见问题,您可以在循环中缓存对象外部:
var permissionCache = new Dictionary<User, bool>();
foreach (var request in requestsList) {
foreach (var myVar in request.anotherList) {
bool permission;
if (!permissionCache.TryGetValue(myVar, out permission)) {
permission = myVar.hasPermissions();
permissionCache.Add(myVar, permission);
}
if (permission) {
//do something
}
}
}
答案 2 :(得分:-1)
我认为你在最上面的循环中称它为最小次数。
如果你以另一种方式思考......
//First get all the 'another' guys:
var allAnother = requestsList.SelectMany(anotherList => anotherList).ToList();
//If you don't have to check them all
var permitGuys = allAnother.Distinct().Where(a => a.hasPermissions()).ToList();
//Do something with them
foreach(var permitGuy in permitGuys)
{
//Do something
}