Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.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 - Fatal编程技术网

C# 我可以做些什么来提高这段代码的性能

C# 我可以做些什么来提高这段代码的性能,c#,linq,C#,Linq,我有这段代码,它可以查看所有联系人,并对发送给他们的每封电子邮件进行计数,如果他们没有打开/单击最后的X金额,则将其返回到列表中 目前代码运行大约需要10分钟,我能做些什么来改进它吗 我知道我可以限制返还的金额,但这仍然很慢 var contactList = (from c in db.Contacts where c.Accounts_CustomerID == Account.AccountID && !c.Deleted &

我有这段代码,它可以查看所有联系人,并对发送给他们的每封电子邮件进行计数,如果他们没有打开/单击最后的X金额,则将其返回到列表中

目前代码运行大约需要10分钟,我能做些什么来改进它吗

我知道我可以限制返还的金额,但这仍然很慢

var contactList =
        (from c in db.Contacts
            where c.Accounts_CustomerID == Account.AccountID && !c.Deleted && !c.EmailOptOut
            select c).ToList();

    foreach (var person in contactList)
    {
        var SentEmails =
            (from c in db.Comms_Emails_EmailsSents where c.ContactID == person.ID select c).OrderBy(
                x => x.DateSent).Take(Last).ToList();

        if (SentEmails.Count == Last)
        {
            if (!Clicks)
            {
                if (SentEmails.Count(x => x.Opens == 0) == Last)
                {
                    ReturnContacts.Add(person);
                }
            }
            else
            {
                if (SentEmails.Count(x => x.Clicks == 0) == Last)
                {
                    ReturnContacts.Add(person);
                }
            }
        }
    }
    return ReturnContacts;

删除.ToList()并使用iQueryTables。通过使用iqueryables,代码将执行一次并减少内存。ToList()检索所有实体并将它们存储在内存中,这是您不需要的。

在db上运行逻辑-使用联接等重写查询,以便返回已包含相关数据的结果集

现在要做的是对每个初始查询结果执行db查询。这可能意味着有很多疑问

如果您将其卸载到RDBMS中,您可以随时尝试并优化它(通过引入索引等)

编辑:我在记事本中重写了代码:

foreach(var record in (from c in db.Contacts
join es in db.Comms_Emails_EmailsSents
on c.Id equals es.ContactId
where c.Accounts_CustomerID == Account.AccountID && !c.Deleted && !c.EmailOptOut
orderby c.Id, es.DateSent descending
select new {opens=es.Opens, clicks=es.Clicks, person=c})
.GroupBy(r=>r.person)){
    var mails = record.Take(Last).ToList();
    if(mails.Count == Last){
        if(!Clicks){
            if(mails.Count(x=>x.opens == 0) == Last){
                 ReturnContacts.Add(record.Key);
            }
        }
    }else
            {
                if (SentEmails.Count(x => x.Clicks == 0) == Last)
                {
                    ReturnContacts.Add(record.Key);
                }
            }

}

我手头没有时间来模拟db并测试它。此外,这种方法在联系人和电子邮件之间执行连接,如果你每人有10万封电子邮件,这可能是一个非常糟糕的主意。您可以使用秩函数对其进行优化,但我想说,如果性能仍然很差,您可以开始考虑进行数据库端优化,因为这种数据结构——至少在我的非dba眼中——并不完全适合这种查询。

使用性能分析器(例如dotTrace)首先,让我们了解一下到底什么进展缓慢。您需要一个连接查询。用sql编写此查询的最佳方法是什么?使用游标?完全不使用游标。。。如有可能;)我将查看代码并尝试更新我的答案。