【问题标题】:Comparing two lists using linq to sql使用 linq to sql 比较两个列表
【发布时间】:2011-10-03 05:29:34
【问题描述】:

假设我有两个列表:

List<CanidateSkill> canidateSkills;
List<JobDesiredSkill> desiredSkills;

class CanidateSkill
{
    public Guid CanidateId { get; set; }
    public Guid SkillId { get; set; }
}

class JobDesiredSkill
{
    public Guid JobId { get; set; }
    public Guid SkillId { get; set; }
}

你如何确定是否:

  1. CandidateSkills 中至少包含 JobDesiredSkills 中的一项(与 SkillId 匹配)

  2. JobDesiredSkills 中的所有项目都包含在 CandidateSkills 中

我试过这个,但得到这个错误:无法创建类型的常量值在这种情况下只支持原始类型('例如 Int32、String 和 Guid')。

 return from candidate in _db.Candidates                           
 where (candidate.CandidateSkills.Any(c => job.JobDesiredSkills.Any(j => j.SkillId == c.SkillId))) 
 select candidate;

我也试过这个,但是 Contains 需要一个 JobDesiredSkill 对象,但 c 是 CandidateSkillObject。

 return from candidate in _db.Candidates                           
 where CandidateSkills.Any(c => JobDesiredSkills.Contains(c)) 
 select candidate;

谢谢

【问题讨论】:

    标签: .net asp.net asp.net-mvc linq entity-framework


    【解决方案1】:

    有两种 linq 方法可以满足您的确切需求:

    1. IEnumerable.Any()
    2. IEnumerable.All()

    编辑:

    您需要在集合中选择“Ids”的“Projection”以获取它们的可枚举集合,然后您可以对它们使用 any/all(如果没有显式比较对象,您无法比较复杂类型) .

    这是一个简单的例子,希望对你有所帮助。

    List<Guid> skills = 
        new List<Guid>( Enumerable.Range( 0, 20 ).Select( n => Guid.NewGuid() ) );
    
    List<CanidateSkill> canidateSkills = new List<CanidateSkill>
    (
        Enumerable.Range( 0, 10 ).Select( c => new CanidateSkill() { CanidateId = Guid.NewGuid(), SkillId = skills.ElementAt( c ) } )
    );
    
    List<JobDesiredSkill> desiredSkills = new List<JobDesiredSkill>
    (
        Enumerable.Range( 5, 15 ).Select( d => new JobDesiredSkill() { JobId = Guid.NewGuid(), SkillId = skills.ElementAt( d ) } )
    );
    
    var anyDesiredSkills = canidateSkills.Any( c => desiredSkills.Select( ds => ds.SkillId ).Contains( c.SkillId ) ); // true
    var allDesiredSkills = canidateSkills.All( c => desiredSkills.Select( ds => ds.SkillId ).Contains( c.SkillId ) ); // false
    

    (注意:我还编辑了您的问题以更新此代码中使用的示例类,希望您不要介意。)

    【讨论】:

    • 您不能使用All 来测试一个序列中的所有项目是否都在另一个序列中 - 您只能使用All 来测试序列中的所有项目是否与给定谓词匹配。不过我可能是错的 - 在这种情况下 2) 的示例用法?
    • @RPM 你只需要构造正确的谓词 - 例如JobDesiredSkills.All(j =&gt; CandidateSkills.Contains(j))
    • @RPM a.All(n => b.Contains(n)); ?
    • 大声笑,我被拥有了,忘记了包含。好的。 :)
    • @RPM 哈哈,我的朋友,我们都去过那里。
    【解决方案2】:

    我现在没有 Visual Studio,但它应该是这样的:

    1.

     JobDesiredSkills.Where(j=&gt;CandidateSkills.Any(c=&gt;c.SkillId == j.SkillId)==true).ToList().Count()&gt;0
    2.
     JobDesiredSkills.Where(j=>CandidateSkills.Where(c=>c.SkillId == j.SkillId).ToList().Count()>0).ToList().Count()==JobDesiredSkills.Count()
    

    【讨论】:

    • 这实际上是我最初尝试的,但我得到了这个错误:无法创建类型为“JobDesiredSkill”的常量值。此上下文仅支持原始类型(“例如 Int32、String 和 Guid”)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多