0

How can I write a linq query to match two condition on same column in the table?

Here one person can be assigned to multiple types of works and it is store in PersonWorkTypes table containing the details of persons and their worktypes.

So I need to get the list of persons who have both fulltime and freelance works.

I have tried

people.where(w => w.worktype == "freelance" && w.worktype == "fulltime")

But it returns an empty result.

4
  • Change the operator from "and" && to "or" || if I'm understanding your goal? What you currently have looks like a guaranteed empty set. Commented Jun 3, 2020 at 3:37
  • Can you please provide sample data for reference purpose? Specify its data structure would be helpful as well. Commented Jun 3, 2020 at 3:37
  • If I understand, you need to get results where worktype is equal to "freelance" OR equal to "fulltime". You're getting null because you are using && operator. Change your condition as egnomerator says. Commented Jun 3, 2020 at 3:52
  • I have updated the question now. here i need to get the person who have both fulltime and freelance works Commented Jun 3, 2020 at 4:03

3 Answers 3

2

You can try this

public class Person {
    public string Name {get;set;}
    public List<PersonWorkType> PersonWorkTypes {get;set;}
}

public class PersonWorkType {
    public string Type {get;set;}
}

public static void Main()
{
    var people = new List<Person>();
    var person = new Person { Name = "Toño", PersonWorkTypes = new List<PersonWorkType>() { new PersonWorkType { Type = "freelance" } } };
    var person2 = new Person { Name = "Aldo", PersonWorkTypes = new List<PersonWorkType>() { new PersonWorkType { Type = "freelance" }, new PersonWorkType { Type = "fulltime" } } };
    var person3 = new Person { Name = "John", PersonWorkTypes = new List<PersonWorkType>() { new PersonWorkType { Type = "freelance" }, new PersonWorkType { Type = "fulltime" } } };

    people.Add(person);
    people.Add(person2);        
    people.Add(person3);

    var filter = people.Where(p => p.PersonWorkTypes.Any(t => t.Type == "freelance") && p.PersonWorkTypes.Any(t => t.Type == "fulltime"));


    foreach(var item in filter) {
        Console.WriteLine(item.Name);
    }
}

This returns person that contains both types in PersonWorkTypes

Sign up to request clarification or add additional context in comments.

1 Comment

You can check this snippet in dotnetfiddle.net/6e3MkL
1

AS already said, && operator means, that BOTH conditions has to be met. So in your condition it means that you want worktype type to by freelanceand fulltime at the same time, which is not possible :)

Most probably you want employees that have work type freelance OR fulltime, thus your condition should be:

people.Where(w=>w.worktype=="freelance" || w.worktype =="fulltime")

Or, if person can be set more than once in this table, then you could do:

people
  .Where(w=>w.worktype=="freelance" || w.worktype =="fulltime")
  // here I assume that you have name of a person,
  // Basically, here I group by person
  .GroupBy(p => p.Name)
  // Here we check if any person has two entries,
  // but you have to be careful here, as if person has two entries
  // with worktype freelance or two entries with fulltime, it
  // will pass condition as well.
  .Where(grp => grp.Count() == 2)
  .Select(grp => grp.FirstOrDefault());

1 Comment

my requirement is not this. I need to get only the persons who are in both freelance and fulltime your query will results in the persons who are in only freelance or fulltime
1
w.worktype=="freelance"
w.worktype=="fulltime"

These are mutually exclusive to each other, and therefore cannot both be true to ever satisfy your AND(&&) operator.

I am inferring that you have two (or more) different rows in your table per person, one for each type of work they do. If so, the Where() method is going to check your list line-by-line individually and won't be able to check two different elements of a list to see if Alice (for example) both has en entry for "freelance" and an entry for "fulltime" as two different elements in the list. Unfortuantely, I can't think of an easy way to do this in a single query, but something like this might work:

var fulltimeWorkers = people.Where(w=>w.worktype=="fulltime");
var freelanceWorkers = people.Where(w=>w.worktype=="freelance");
List<Person> peopleWhoDoBoth = new List<Person>();
foreach (var worker in fulltimeWorkers)
{
   if (freelanceWorkers.Contains(worker)
      peopleWhoDoBoth.Add(worker);
}

This is probably not the most efficient way possible of doing it, but for small data sets, it shouldn't matter.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.