c# – LINQ查询,用于选择与对数组匹配的行

现在,我有一个名为TrainingPlan的类,如下所示:

public class TrainingPlan
{
   public int WorkgroupId { get; set; }
   public int AreaId { get; set; }
}

我得到了一些这样的实例,需要从数据库中加载匹配的培训计划. WorkgroupId和AreaId基本上形成复合键.我现在正在做的是循环遍历每个TrainingPlan,如下所示:

foreach (TrainingPlan plan in plans)
   Loadplan(pid,plan.AreaId,plan.WorkgroupId);

然后,Loadplan有一个LINQ查询来加载单个计划:

var q = from tp in context.TPM_TRAININGPLAN.Include("TPM_TRAININGPLANSOLUTIONS")
        where tp.PROJECTID == pid && tp.AREAID == areaid &&
              tp.WORKGROUPID == workgroupid
              select tp;

return q.FirstOrDefault();

问题:

这是有效的,但对于大量计划而言,这是非常缓慢的.我相信如果我可以执行单个LINQ查询以立即加载每个TPM_TRAININGPLAN,这可能会快得多.

我的问题:

给定一组TrainingPlan对象,如何一次加载每个匹配的WorkgroupId / AreaId组合?此查询应转换为类似的sql语法:

SELECT * FROM TPM_TRAININGPLANS
WHERE (AREAID,WORKGROUPID) IN ((1,2),(3,4),(5,6),(7,8));

解决方法

我使用Contains运行类似于where-in的批量过滤器.我设置了一个粗略的近似场景.单个选择查询实际上比Contains运行得更快.我建议你在数据库中运行一个类似的测试,看看你的结果如何结束.理想情况下,看它如何扩展.我在visual studio 2012中运行.NET 4.0.我在ToList()调用中遇到了阻塞以推迟潜在的延迟加载问题.

public class TrainingPlan
{
    public int WorkgroupId { get; set; }
    public int AreaId { get; set; }

    public TrainingPlan(int workGroupId,int areaId)
    {
        WorkgroupId = workGroupId;
        AreaId = areaId;
    }    
}

public class TrainingPlanComparer : IEqualityComparer<TrainingPlan>
{
    public bool Equals(TrainingPlan x,TrainingPlan y)
    {
        //Check whether the compared objects reference the same data. 
        if (x.WorkgroupId == y.WorkgroupId && x.AreaId == y.AreaId) 
            return true;

        return false;                        
    }

    public int GetHashCode(TrainingPlan trainingPlan)
    {            
        if (ReferenceEquals(trainingPlan,null)) 
            return 0;

        int wgHash = trainingPlan.WorkgroupId.GetHashCode();
        int aHash = trainingPlan.AreaId.GetHashCode();

        return wgHash ^ aHash;
    }
}


internal class Class1
{
    private static void Main()
    {
        var plans = new List<TrainingPlan>
            {
                new TrainingPlan(1,new TrainingPlan(1,3),new TrainingPlan(2,1),2)
            };

        var filter = new List<TrainingPlan>
            {
                new TrainingPlan(1,};

        Stopwatch resultTimer1 = new Stopwatch();
        resultTimer1.Start();
        var results = plans.Where(plan => filter.Contains(plan,new TrainingPlanComparer())).ToList();
        resultTimer1.Stop();

        Console.WriteLine("Elapsed Time for filtered result {0}",resultTimer1.Elapsed);

        Console.WriteLine("Result count: {0}",results.Count());

        foreach (var item in results)
        {
            Console.WriteLine("WorkGroup: {0},Area: {1}",item.WorkgroupId,item.AreaId);
        }

        resultTimer1.Reset();

        resultTimer1.Start();
        var result1 = plans.Where(p => p.AreaId == filter[0].AreaId && p.WorkgroupId == filter[0].WorkgroupId).ToList();
        var result2 = plans.Where(p => p.AreaId == filter[1].AreaId && p.WorkgroupId == filter[1].WorkgroupId).ToList();
        resultTimer1.Stop();

        Console.WriteLine("Elapsed time for single query result: {0}",resultTimer1.Elapsed);//single query is faster

        Console.ReadLine();
    }
}

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...