我有一个需要永远运行的SQL查询。我知道问题出在哪里,但我不知道如何解决它。
这是我的代码:
var result = context.Persons.OrderByDescending(x => x.PersonId);
var response = result.Where(x => x.IsProvider.Equals(false) && x.Obsolete.Equals(false) && x.Locked.Equals(false) && x.IsCustomer.Equals(true));
var list = new List<ICustomerHead>();
foreach (var customer in response)
{
if (!customer.PersonType.Equals(2))
{
list.Add(customer.ToSingleCustomerHead());
}
}
foreach (var customer in list) //This loop is the problem, because it will make a new db connection for every customer
{
var companyResult = context.Companies.SingleOrDefault(x => x.CompanyId.Equals(customer.Id));
if (companyResult != null)
customer.Email = companyResult.StandardEMail;
}
return list;
第二个循环是延迟的位置。这是因为它将为每个客户建立一个新的数据库连接。那么我怎样才能让它更快?
请帮助:)
答案 0 :(得分:2)
简单 - 如果您有一个ID列表,并且您希望一个选择查询获得该列表中具有ID的所有公司,则需要使用.Contains(在SQL中转换为IN
)
以下是:
var idList = list.Select(x => x.Id);
// create a query that just gets the required emails and companyIds.
var emails = context.Companies.Where(x => idList.Contains(x.CompanyId))
.Select(x => new {x.CompanyId, x.StandardEmail});
// execute the query (with .ToList() )
// and then iterate through the results, setting e-mail address on the list items
emails.ToList().ForEach(
x => list.First(y => y.Id == x.CompanyId).Email = x.StandardEmail
);
说实话,虽然我可能只是做一个查询,让您的客户与他们的电子邮件地址在一击。
例如:
var list = new List<ICustomerHead>();
var query = from p in context.Persons
join c in context.Companies on p.CompanyId equals c.CompanyId
where p.IsProvider.Equals(false)
&& p.Obsolete.Equals(false)
&& p.Locked.Equals(false)
&& p.IsCustomer.Equals(true)
&& !p.PersonType.Equals(2) // not sure why this was separate before?
select new {p, c.StandardEmail};
foreach(var item in query.ToList()) //ToList() causes the query to execute
{
var customer = item.p.ToSingleCustomerHead(); //assume this is an extension method you've added?
customer.Email = item.StandardEMail;
list.Add(customer);
}
答案 1 :(得分:0)
假设公司是相关实体,您可以在第一次查询中使用Include公司
添加此引用以使用Include lambda(使用System.Data.Entity;)
var response = result.Include(x=>x.Companies).Where(x => x.IsProvider.Equals(false) && x.Obsolete.Equals(false) && x.Locked.Equals(false) && x.IsCustomer.Equals(true));
添加
foreach (var customer in response)
{
if (!customer.PersonType.Equals(2))
{
var c =customer.ToSingleCustomerHead();
if (customer.Companies !=null && customer.Companies.FirstOrDefaultOrDefault() != null)
c.Email = companyResult.StandardEMail;
list.Add(c);
}
}
注意:FirstOrDefaultOrDefault比SingleOrDefault更快,bacasuse singleOrDefault检查uninque值。