我有一个查询有时返回几行但执行时间很长。我想知道为什么需要这么长时间,我该如何解决它。这是代码:
public IList<SearchUserResult> SearchLegacyUsers(string userName, string email, string firstName, string lastName, string city, int? stateID,
string postalCode, int? countryID)
{
using (var db = new MyModel.MyContext())
{
var users = (from pu in db.PersonUsernames
from pe in db.PersonEmails.Where(a => a.PersonID == pu.PersonID).DefaultIfEmpty()
from p in db.People.Where(b => b.UPID == pu.PersonID).DefaultIfEmpty()
from pa in db.Addresses.Where(c => c.PersonID == pu.PersonID).DefaultIfEmpty()
from sc in db.LU_State.Where(d => d.ID == pa.StateID).DefaultIfEmpty()
from pp in db.Phones.Where(e => e.UPID == pu.PersonID).DefaultIfEmpty()
select new SearchUserResult
{
PersonID = p.UPID,
UserName = pu.Username,
Email = pe.Email,
FirstName = p.FirstName,
MiddleName = p.MiddleName,
LastName = p.LastName,
Address = pa.Address1,
City = pa.City,
StateCode = sc.StateAbbr,
StateID = sc.ID,
PostalCode = pa.Zip,
Phone = pp.PhoneNumber,
CountryCode = sc.LU_Country.Name,
CountryID = sc.LU_Country.ID
}).ToList();
if (!string.IsNullOrEmpty(userName)) users = users.Where(a => a.UserName.Contains(userName)).ToList();
if (!string.IsNullOrEmpty(email)) users = users.Where(b => b.Email != null && b.Email.Contains(email)).ToList();
if (!string.IsNullOrEmpty(firstName)) users = users.Where(c => c.FirstName.Contains(firstName)).ToList();
if (!string.IsNullOrEmpty(lastName)) users = users.Where(d => d.LastName.Contains(lastName)).ToList();
if (!string.IsNullOrEmpty(city)) users = users.Where(e => e.City.Contains(city)).ToList();
if (stateID != null && stateID != 0)
{
users = users.Where(f => f.StateID == stateID).ToList();
}
if (!string.IsNullOrEmpty(postalCode)) users = users.Where(g => g.PostalCode.Contains(postalCode)).ToList();
if (countryID != null && countryID != 0)
{
users = users.Where(h => h.CountryID == countryID).ToList();
}
return users;
}
}
任何改进的想法都非常受欢迎。
答案 0 :(得分:0)
System.Linq
命名空间有2个静态类,允许您使用LINQ查询和/或顺序(即Array,List,String)。这些类是Enumerable
,其扩展方法适用于IEnumerable<T>
类型。并Queryable
处理IQueryable<>
类型。
第一种类型的方法在内存中执行,第二种方法将代码转换为SQL并将其脚本发送到数据库。
IQueryable<T>
类型继承自IEnumerable<T>
,两者都在枚举时执行。默认情况下,数据库上下文中的所有序列都来自IQueryable<T>
类型。
以下是如何通过枚举来执行查询的一些示例:
// these sentenses are all enumerated immediately
db.PersonUsernames.ToList();
db.PersonUsernames.Where(a => a.PersonID != 39).ToArray();
db.PersonUsernames.Count();
foreach(var person in db.PersonUsernames) { /* Do something */ }
// but, these are not
string name = "";
var query = db.PersonUsernames.Where(a => a.PersonID != 39);
if (String.IsNullOrEmpty(name))
query = query.Where(a => a.UserName == name);
query = query.OrderBy(q => q.PersonID);
// and when you want to enumerate it
// you just have to call ToList or enumerate it using foreach
query.ToList();
query.ToArray();
foreach(var q in query) { /* Do something */ }
所以你的代码看起来像这样:
public IList<SearchUserResult> SearchLegacyUsers(string userName, string email, string firstName, string lastName, string city, int? stateID,
string postalCode, int? countryID)
{
using (var db = new MyModel.MyContext())
{
var users = (from pu in db.PersonUsernames
from pe in db.PersonEmails
.Where(a => a.PersonID == pu.PersonID)
.DefaultIfEmpty()
from p in db.People
.Where(b => b.UPID == pu.PersonID)
.DefaultIfEmpty()
from pa in db.Addresses
.Where(c => c.PersonID == pu.PersonID)
.DefaultIfEmpty()
from sc in db.LU_State
.Where(d => d.ID == pa.StateID)
.DefaultIfEmpty()
from pp in db.Phones
.Where(e => e.UPID == pu.PersonID)
.DefaultIfEmpty()
// when you use DefaultIfEmpty, you're saying that
// if this sequence does not contain any item
// it'll return a sequense with just 1 null item.
// So, you have to verify if pe, p, pa, sc and pp
// is different of null
select new SearchUserResult
{
PersonID = p.UPID,
UserName = pu.Username,
Email = pe.Email, // pe != null ? pe.Email : "",
FirstName = p.FirstName,
MiddleName = p.MiddleName,
LastName = p.LastName,
Address = pa.Address1,
City = pa.City,
StateCode = sc.StateAbbr,
StateID = sc.ID,
PostalCode = pa.Zip,
Phone = pp.PhoneNumber,
CountryCode = sc.LU_Country.Name,
CountryID = sc.LU_Country.ID
});
if (!string.IsNullOrEmpty(userName))
users = users.Where(a => a.UserName.Contains(userName));
if (!string.IsNullOrEmpty(email))
users = users.Where(b => b.Email != null && b.Email.Contains(email));
if (!string.IsNullOrEmpty(firstName))
users = users.Where(c => c.FirstName.Contains(firstName));
if (!string.IsNullOrEmpty(lastName))
users = users.Where(d => d.LastName.Contains(lastName));
if (!string.IsNullOrEmpty(city))
users = users.Where(e => e.City.Contains(city));
if (stateID != null && stateID != 0)
{
users = users.Where(f => f.StateID == stateID);
}
if (!string.IsNullOrEmpty(postalCode))
users = users.Where(g => g.PostalCode.Contains(postalCode));
if (countryID != null && countryID != 0)
{
users = users.Where(h => h.CountryID == countryID);
}
// finally, you can execute the query
return users.ToList();
}
}
如果您想了解有关LINQ的更多信息,建议您阅读Syncfusion ebook about LINQ
我希望它对您有所帮助,如果有,请将其标记为答案。