为什么这个linq查询的匿名类型比我尝试的任何其他类型更快?

The*_*arf 0 c# sql linq performance

我有这个查询,它从表中选择了很多用户记录.这个代码块从我的本地/调试机器需要16秒(在生产中更像是5).为了提高效率,我所做的任何事情都会使方法返回结果所花费的时间增加一倍.我试过的其他事情的例子如下.我不明白如何选择一个匿名类型并且通过匿名类型迭代的额外中间部分可能比没有更快.

这个块需要16秒:

List<BoAssetSecurityUser> userList = new List<BoAssetSecurityUser>();
using (var context = DataObjectFactory.CreateContext())
{

    var query = from ui in context.User_Information
                where (ui.AssetCustomerID == 1 && 
                          (ui.GlobalID != "1TPTEMPUSER" || 
                           ui.GlobalID == null))
                select new { ui };
    var result =
    from q in query
    select new
    {
        UserId = q.ui.UserID,
        FirstName = q.ui.FirstName,
        LastName = q.ui.LastName,
        UserName = q.ui.Username,
        Globalid = q.ui.GlobalID

    };
    foreach (var user in result)
    {
        BoAssetSecurityUser boAssetSecUser = new BoAssetSecurityUser();
        boAssetSecUser.UserId = user.UserId;
        boAssetSecUser.FirstName = user.FirstName;
        boAssetSecUser.LastName = user.LastName;
        boAssetSecUser.UserName = user.UserName;
        boAssetSecUser.GlobalId = user.Globalid;
        userList.Add(boAssetSecUser);
    }
}
return userList;
Run Code Online (Sandbox Code Playgroud)

这需要45秒才能完成:

List<BoAssetSecurityUser> userList = new List<BoAssetSecurityUser>();
using (var context = DataObjectFactory.CreateContext())
{

    var query = (from ui in context.User_Information
                where (ui.AssetCustomerID == 1 && 
                          (ui.GlobalID != "1TPTEMPUSER" || 
                           ui.GlobalID == null))
                select ui).ToList();
    foreach (var user in query)
    {
        BoAssetSecurityUser boAssetSecUser = new BoAssetSecurityUser();
        boAssetSecUser.UserId = user.UserID;
        boAssetSecUser.FirstName = user.FirstName;
        boAssetSecUser.LastName = user.LastName;
        boAssetSecUser.UserName = user.Username;
        boAssetSecUser.GlobalId = user.GlobalID;
        userList.Add(boAssetSecUser);
    }
}
return userList;
Run Code Online (Sandbox Code Playgroud)

此示例还需要45秒才能完成:

List<BoAssetSecurityUser> userList = new List<BoAssetSecurityUser>();
using (var context = DataObjectFactory.CreateContext())
{

    var query = from ui in context.User_Information
        where (ui.AssetCustomerID == 1 && 
                  (ui.GlobalID != "1TPTEMPUSER" || 
                   ui.GlobalID == null))
                select new { ui };

    foreach (var user in query)
    {
        BoAssetSecurityUser boAssetSecUser = new BoAssetSecurityUser();
        boAssetSecUser.UserId = user.ui.UserID;
        boAssetSecUser.FirstName = user.ui.FirstName;
        boAssetSecUser.LastName = user.ui.LastName;
        boAssetSecUser.UserName = user.ui.Username;
        boAssetSecUser.GlobalId = user.ui.GlobalID;

        userList.Add(boAssetSecUser);
    }
}
return userList;
Run Code Online (Sandbox Code Playgroud)

Tim*_* S. 5

这很可能是因为ui's类型具有比你感兴趣的5更多的属性.new { ui }匿名类型是不必要的; 您的第一个示例更快,因为您在迭代列表(因此转到数据库)之前告诉它您只对这5个字段感兴趣.在其他示例中,您迭代列表,从而拉动整个ui对象,即使您只使用其5个属性.

此代码应该只提取5个属性,因此与第一个示例一样快,同时更简洁:

List<BoAssetSecurityUser> userList = new List<BoAssetSecurityUser>();
using (var context = DataObjectFactory.CreateContext())
{
    var query = from ui in context.User_Information
                where (ui.AssetCustomerID == 1 && (ui.GlobalID != "1TPTEMPUSER" || ui.GlobalID == null))
                select new
                {
                    ui.UserID,
                    ui.FirstName,
                    ui.LastName,
                    ui.Username,
                    ui.GlobalID
                };

    foreach (var user in query)
    {
        BoAssetSecurityUser boAssetSecUser = new BoAssetSecurityUser();
        boAssetSecUser.UserId = user.UserID;
        boAssetSecUser.FirstName = user.FirstName;
        boAssetSecUser.LastName = user.LastName;
        boAssetSecUser.UserName = user.Username;
        boAssetSecUser.GlobalId = user.GlobalID;
        userList.Add(boAssetSecUser);
    }
}
return userList;
Run Code Online (Sandbox Code Playgroud)