如何根据列表中的项筛选查询结果?

时间:2013-12-16 09:17:18

标签: c# .net linq

在我的网站上,我有一个搜索功能。当用户想要搜索时,创建一个包含搜索条件的对象。它看起来像这样:

public class SearchJSON : ISearchObject
{
    public List<String> sites { get; set; }
    public int minWage { get; set; }
    public int maxWage { get; set; }
    public List<String> countries { get; set; }
    public int minRating { get; set; }
    public int maxRating { get; set; }
    public int pageNumber { get; set; }
    public List<String> skills { get; set; }

}

我的应用程序数据库结构,类及其关系:

enter image description here

有一个函数可以查询数据库并根据用户输入的搜索条件检索自由职业者列表:

    var query = db.Freelancers
                   .Include("Skills").Include("Countries")
                   .Where(x => x.HourWageMin >= data.minWage)
                   .Where(x => x.HourWageMax <= data.maxWage)
                   .Where(x => x.Stars >= data.minRating)
                   .Where(x => x.Stars <= data.maxRating)
                   .Where(x => x.Countries != null && data.countries.Contains(x.Countries.Name));

问题是我想过滤掉skills对象的“SearchJSON”列表中没有技能的人。我如何用我的lambda表达式做到这一点?

2 个答案:

答案 0 :(得分:0)

您有急需加载的原因吗?如果不是,请进行延迟加载并编写类似

的内容
db.Freelancers.Where( f => f.Skills.Where(s => s.Name == data.Name).Any()).ToList();

现在,如果你不能使用延迟加载,你可以使用如下所示的显式加载

db.Freelancers
   .Collection(p => p.Skills)
   .Query()
   .Where(u => u.Name.StartsWith("B"))
   .Load();

到目前为止,我认为你不能用include(string)实现你想要的东西。

答案 1 :(得分:0)

var query = db.Freelancers
               .Include("Skills").Include("Countries")
               .Where(x => x.HourWageMin >= data.minWage)
               .Where(x => x.HourWageMax <= data.maxWage)
               .Where(x => x.Stars >= data.minRating)
               .Where(x => x.Stars <= data.maxRating)
               .Where(x => x.Countries != null && data.countries.Contains(x.Countries.Name))
               .Where(x => x.Skills.Any(s => data.skills.Contains(s.Name)));

样本测试返回两名自由职业者:

internal void Run()
{
    //Seed();
    List<string> skills = new List<string>() { "Skill 1", "Skill 2" };
    var query = context.Freelancers
            .Include("Skill")
            .Where(x => x.Skill.Any(s => skills.Contains(s.Name)));
    // query returns two freelancers, 1 and 3.
}

private void Seed()
{

    Skill s1 = new Skill() { Name = "Skill 1" };
    Skill s2 = new Skill() { Name = "Skill 2" };
    Skill s3 = new Skill() { Name = "Skill 3" };
    Skill s4 = new Skill() { Name = "Skill 4" };
    Skill s5 = new Skill() { Name = "Skill 5" };
    Skill s6 = new Skill() { Name = "Skill 6" };

    Freelancer f1 = new Freelancer() { Name = "Freelancer 1" };
    f1.Skill.Add(s1);
    f1.Skill.Add(s3);
    f1.Skill.Add(s4);
    f1.Skill.Add(s6);

    Freelancer f2 = new Freelancer() { Name = "Freelancer 2" };
    f2.Skill.Add(s4);
    f2.Skill.Add(s6);

    Freelancer f3 = new Freelancer() { Name = "Freelancer 3" };
    f3.Skill.Add(s1);
    f3.Skill.Add(s6);

    Freelancer f4 = new Freelancer() { Name = "Freelancer 4" };
    f4.Skill.Add(s5);

    context.Freelancers.Add(f1);
    context.Freelancers.Add(f2);
    context.Freelancers.Add(f3);
    context.Freelancers.Add(f4);

    context.SaveChanges();
}

生成此sql查询:

{SELECT 
[Project2].[Id] AS [Id], 
[Project2].[Name] AS [Name], 
[Project2].[Country_Id] AS [Country_Id], 
[Project2].[C1] AS [C1], 
[Project2].[Id1] AS [Id1], 
[Project2].[Name1] AS [Name1]
FROM ( SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[Name] AS [Name], 
[Extent1].[Country_Id] AS [Country_Id], 
[Join1].[Id] AS [Id1], 
[Join1].[Name] AS [Name1], 
CASE WHEN ([Join1].[Skill_Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM  [dbo].[Freelancers] AS [Extent1]
LEFT OUTER JOIN  (SELECT [Extent2].[Skill_Id] AS [Skill_Id], [Extent2].[Freelancer_Id] AS [Freelancer_Id], [Extent3].[Id] AS [Id], [Extent3].[Name] AS [Name]
    FROM  [dbo].[SkillFreelancer] AS [Extent2]
    INNER JOIN [dbo].[Skills] AS [Extent3] ON [Extent3].[Id] = [Extent2].[Skill_Id] ) AS [Join1] ON [Extent1].[Id] = [Join1].[Freelancer_Id]
WHERE  EXISTS (SELECT 
    1 AS [C1]
    FROM  [dbo].[SkillFreelancer] AS [Extent4]
    INNER JOIN [dbo].[Skills] AS [Extent5] ON [Extent5].[Id] = [Extent4].[Skill_Id]
    WHERE ([Extent1].[Id] = [Extent4].[Freelancer_Id]) AND ([Extent5].[Name] IN (N'Skill 1',N'Skill 2'))
)
)  AS [Project2]
ORDER BY [Project2].[Id] ASC, [Project2].[C1] ASC}