Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# Linq在select语句中调用方法的速度非常慢_C#_Linq - Fatal编程技术网

C# Linq在select语句中调用方法的速度非常慢

C# Linq在select语句中调用方法的速度非常慢,c#,linq,C#,Linq,我试图找出是否有一种方法可以从我的linq select语句中调用一个方法来构建一个不会显著降低速度的对象列表。这背后的原因是,我还希望在尝试仅获取其中一个对象时调用相同的方法,并且不希望必须维护两个版本,即,如果我在对象中添加了另一个字段,或者希望以不同的方式呈现其中一个字段,我将不必在多个位置对其进行更改 在下面的示例中,测试1的运行速度比测试2快100倍以上: // Start timer var timer = new Stopwatch(); timer.Start(); var t

我试图找出是否有一种方法可以从我的linq select语句中调用一个方法来构建一个不会显著降低速度的对象列表。这背后的原因是,我还希望在尝试仅获取其中一个对象时调用相同的方法,并且不希望必须维护两个版本,即,如果我在对象中添加了另一个字段,或者希望以不同的方式呈现其中一个字段,我将不必在多个位置对其进行更改

在下面的示例中,测试1的运行速度比测试2快100倍以上:

// Start timer
var timer = new Stopwatch();
timer.Start();

var test = (from job in dc.Jobs
        where !job.archived
        select new JobExtended()
        {
            JobId = job.jobId,
            NodeId = job.nodeId,
            JobName = job.name != string.Empty ? job.name : "TBC",
            Salary = job.salary,
            RecruiterId = job.fkRecruiterId,
            RecruiterNodeId = job.JobRecruiter != null ? job.JobRecruiter.recruiterNodeId : null,
            RecruiterName = job.JobRecruiter != null ? job.JobRecruiter.name : string.Empty,
            LocationId = job.fkLocationId,
            Location = job.refJobLocation != null ? job.refJobLocation.jobLocation : "",
            ContractTypeId = job.fkContractTypeId,
            ContractType = job.refJobContractType != null ? job.refJobContractType.contractType : "",
            CategoryId = job.fkCategoryId,
            Category = job.refJobCategory != null ? job.refJobCategory.category : "",
            ClosingDate = job.closingDate,
            Featured = job.featured,
            JobOfTheWeek = job.jobOfTheWeek,
            PublishedDate = job.publishedDate,
            Url = "/jobs/" + job.name.Replace(" ", "-").Replace("&", "and").Replace("'", "") + (job.fkLocationId.HasValue ? "-in-" + job.refJobLocation.jobLocation.Replace(" ", "-").Replace("&", "and").Replace("'", "") : "") + "-jn" + job.jobId,
            CreatedOn = job.createdOnDate,
            PrintWidth = job.printWidth,
            PrintHeight = job.printHeight,
            UntilFilled = (job.untilFilled != null && job.untilFilled.Value),
            AdvertCost = job.advertCost,
            DatesToShow = job.relJobDates.Where(x => x.fkJobId == job.jobId).Select(x => x.date).ToList(),
            IsParentJob = job.relLinkedJobs != null && job.relLinkedJobs.Any(x => x.fkParentJobId == job.jobId),
            IsAlternateWeekJob = job.alternateWeek != null && job.alternateWeek.Value,
            Archived = job.archived,
            LastModifiedDate = job.lastModifiedDate,
            RecruiterContactDetails = job.recruiterContactDetails
        }).ToList();

// Stop timer
timer.Stop();

// Output info
litTest.Text = "TEST 1 in " + timer.Elapsed.TotalSeconds + " seconds<br/>";

//Start timer
timer = new Stopwatch();
timer.Start();

var test2 = (from job in dc.Jobs
            where !job.archived
            select GetJobDetails(job)).ToList();

//Stop timer
timer.Stop();

//Output info
litTest.Text += "TEST 2 in " + timer.Elapsed.TotalSeconds + " seconds<br/>";
这是因为我希望能够调用GetJobDetails返回单个作业,例如:

    public JobExtended GetJobDetails(int jobId)
    {
        using (DataContext dc = new DataContext())
        {
            return dc.Jobs.Where(x => x.jobId == jobId).Select(j => GetJobDetails(j)).FirstOrDefault();
        }
    }
如果我决定添加一个新的字段来更改Url值的生成方式,那么这样做只允许我更新GetJobDetails方法,但是这样做要慢得多。有没有办法解决这个问题,我已经尝试了以下似乎没有帮助的方法:

var test3 = (from job in dc.Jobs
                where !job.archived
                select job).AsEnumerable()
                .Select(GetJobDetails).ToList();

var test4 = (from job in dc.Jobs
                where !job.archived
                select GetJobDetails(job));
var test4a = test4.ToList();

我以前见过这种问题。如果我还记得的话,我们所做的就是将查询叠加起来

public IEnumerable<JobExtended> ConvertToJobExtended(IEnumerable<Job> jobs)
{
    return
        from job in jobs
        select new JobExtended()
        {
            MyString = job.MyInt.ToString(),
            ...
        };
}

从这里可以有很多选择。。。我希望这是您希望做的事情的正确方向。

原因测试1更快,因为查询在服务器上执行一次,并且只返回所选字段

var test = (from job in dc.Jobs
    where !job.archived
    select new JobExtended()
    {
        JobId = job.jobId,
        NodeId = job.nodeId,
        ...
    }).ToList();
当您在测试2中调用GetJobDetails时,需要首先具体化参数j,然后才能将其作为参数发送给GetJobDetails。所以有多个完整对象的调用

return dc.Jobs.Where(x => x.jobId == jobId).Select(j => GetJobDetails(j)).FirstOrDefault();
为了达到您想要的效果,您应该使用扩展方法。这一个扩展了IQueryable

    public static IEnumerable<JobExtended> SelectJobExtended(this IQueryable<Data.Job> query)
    {
        return query
            .Select(o => new JobExtended()
            {
                JobId = job.jobId,
                NodeId = job.nodeId,
                ...
            }
    }

JobExtended的构造函数应该只接受一个参数,即Data.Job。分配属性和检查其他内容应该在构造函数内部完成。我这么说是因为你有很多财产。您的代码将减少为返回新的JobExtendedjob;。。。。你在一行中做的太多了。这就是我想说的。@m.kazemAkhgary您的解决方案是将JobExtended类型构造函数与Job类型紧密耦合,这可能是不可取的。我尝试了这个方法,但它似乎根本没有改善性能。您使用的是IEnumerable还是IQueryable?另外,请注意,最后只调用了一次ToList。我尝试了此操作,但在SelectJobExtended方法中收到以下错误:其他信息:无法将表达式“TableJob.Wherex=>Notx.archived”转换为SQL,并且无法将其视为本地表达式。它应该是。Selectjob=>new JobExtended。。。{ .. };IList应该是IEnumerable。我已经更新了答案。我使用这个方法工作,我的问题是我在SelectJobExtended方法中使用了String.IsNullOrEmpty。
return dc.Jobs.Where(x => x.jobId == jobId).Select(j => GetJobDetails(j)).FirstOrDefault();
    public static IEnumerable<JobExtended> SelectJobExtended(this IQueryable<Data.Job> query)
    {
        return query
            .Select(o => new JobExtended()
            {
                JobId = job.jobId,
                NodeId = job.nodeId,
                ...
            }
    }
dc.Jobs.Where(x => x.jobId == jobId).SelectJobExtended().FirstOrDefault();