微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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();
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐