我有Web Method
查询Outlook以从Global Address List
获取所有通讯组列表。
这抓住了超过4,000个分发列表,这正是我想要它做的,但当它进入循环以将4,000个列表传递到我的List
时,它需要3分钟才能完成for循环。任何人都可以看到任何与众不同的东西并回答为什么会发生这种情况吗?
这是我的代码:
public class DistributionListDetails
{
public int DistributionListId { get; set; }
public string DistributionListEmail { get; set; }
}
List<DistributionListDetails> distributionLists = new List<DistributionListDetails>();
int val = 0;
//create Outlook application.
Outlook.Application oApp = new Outlook.Application();
//get Mapi NameSpace and Logon.
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
//get Global Address List.
Outlook.AddressLists oDLs = oNS.AddressLists;
Outlook.AddressList oGal = oDLs["Global Address List"];
//get a specific distribution list.
string sDL = "TestDL";
Outlook.AddressEntries oEntries = oGal.AddressEntries;
Outlook.AddressEntry oDL = oEntries[sDL];
if (oDL.Manager != null)
distributionLists.Add(new DistributionListDetails
{
DistributionListId = val,
DistributionListEmail = oDL.Manager.ToString()
});
//get all of the members of the distribution list.
oEntries = oDL.Members;
Outlook.AddressEntry oEntry = default(Outlook.AddressEntry);
int i = 0;
for (i = 1; i <= oGal.AddressEntries.Count && i <= 10; i++)
{
oEntry = oGal.AddressEntries[i];
distributionLists.Add(new DistributionListDetails
{
DistributionListId = val,
DistributionListEmail = oEntry.Name
});
}
注意:我通过AJAX将循环中返回的列表绑定到下拉列表。
答案 0 :(得分:1)
假设对AD的查询不是瓶颈,请尝试使用此LINQ for size。它取代了你的最后一个循环。
distributionLists.AddRange(oGal.AddressEntries
.Cast<Outlook.AddressEntry>()
.Select(
x => new DistributionListDetails
{
DistributionListId = val,
DiestributionListEmail = x.Name
}));
编辑:强制将AddressEntries转换为IQueryable,因此select将起作用。
答案 1 :(得分:0)
I guess you are running this method to grab distribution lists every time someone calls this method. Instead of doing that, it's better to cachce the distribution lists and access them from cache when needed.
答案 2 :(得分:0)
If you were using C++ or Delphi, you could use AddressEntires.RawTable
(returns IMAPITable MAPI object) and use IMAPITable::SetColumns/QueryRows
or HrQueryAllRows
.
If using Redemption is an option, you could use it MAPITable object. Off the top of my head:
Redemption.MAPITable table = new Redemption.MAPITable();
table.Item = oGal.AddressEntries;
ADODB.Recordset recordset = table.ExecSQL("SELECT name from Table");
while (!recordset.EOF)
{
string name = recordset.Fields(0).Value;
recordset.MoveNext();
}