3

Im sure there is some way to write this code in Linq. But I'm new to LINQ and don't know how to do it? Here is the code:

List<IEntityMITARBEITER> leiter = new List<IEntityMITARBEITER>();
        foreach (IEntityMITARBEITER mitarbeiter in mit)
        {
            foreach (IEntityREF_SCHULLUNG refs in refSchullung)
            {
                if (refs.Id_person == mitarbeiter.Id_mit)
                {
                    leiter.Add(mitarbeiter);
                }

            }

        }
Luke
  • 5,771
  • 12
  • 55
  • 77
  • What is refSchullung? You're looking up ids in it by scanning the complete list / array / etc. Can you turn this into a dictionary of ID to object, or just a set of IDs, which you could query faster? – Rup Sep 08 '11 at 14:56
  • and will refSchullung ever hold the same Id_person more than once? At the moment you'd get two lieter entries for the same mitarbeiter Id_mit if it did. – Rup Sep 08 '11 at 14:58

4 Answers4

7
leiter = mit.Where(x => refSchullung.Any(y => y.Id_person == x.Id_mit)).ToList();

(in case the co-worker doesn't appear in more courses.)

nothrow
  • 15,882
  • 9
  • 57
  • 104
2
var selectedMitarbeiter = mit
       .Where(m => refSchulung.Any(s => s.Id_person == m.Id_mit));
leiter.AddRange(selectedMitarbeiter.ToList());
Dennis Traub
  • 50,557
  • 7
  • 93
  • 108
1

why do you want re-write it using LINQ? What you have done is ok:it is very readable and much faster than it would be in LINQ

If you really want to use LINQ I can suggest you to install ReSharper which will convert it for you.

http://blogs.jetbrains.com/dotnet/2009/12/resharper-50-preview-loops-2-linq/

Massimiliano Peluso
  • 26,379
  • 6
  • 61
  • 70
  • Well, first I want to learn LINQ. Second I find this code is very cumbersome and I think Linq looks far more elegant. – Luke Sep 08 '11 at 14:53
  • If he did it in LINQ he could use a join which would (I think) load the IDs into a hashset so he wouldn't be doing complete scans of refSchullung. So I'd think the LINQ would be faster. – Rup Sep 08 '11 at 14:54
  • 2
    As for being faster, this code might actually be slower as it will continue iterating even after it's decided to add the parent to the list. Using `Any` in LINQ would cause the iteration to stop on first success. – Adam Houldsworth Sep 08 '11 at 14:55
  • if the code is well written a classic for will be always much faster than LINQ – Massimiliano Peluso Sep 08 '11 at 14:55
  • `if the code is well written a classic for will be always much faster than LINQ` -> not true. for example, pLINQ may use multiple threads without any change to code, so there may be significant performance improvements using LINQ than code (in LINQ, you specify what you want to be selected, not the way how to do it, and the compiler/runtime may choose something better) – nothrow Sep 08 '11 at 14:58
  • @Adam Houldsworth you can improve it using "break" or "continue " depends by what he needs to do. In that case the for each will be faster. – Massimiliano Peluso Sep 08 '11 at 14:59
  • 2
    @Massimiliano premature optimisation at best I'm afraid. A lot of the time I find LINQ provides more readable code, which I would rank as more important than the speed of constructs where performance is acceptable or not perceivable. I'm aware of how he can improve it, but as it stands the OP doesn't use it and your answer doesn't state it. – Adam Houldsworth Sep 08 '11 at 15:00
  • No, pLINQ is implementation of LINQ. There is, in fact, no 'pure' LINQ, it is pure abstract. In this case LINQ used is linq to objects. There may be even better implementation than naive foreach(), which can be chosen by runtime, without modifying the code at all. – nothrow Sep 08 '11 at 15:04
  • @Adam I agree you about the code is more readable(I have state it on my question) LINQ internally uses classic for so my thinking is if the code is really complex and difficult to read it is better use LINQ otherwise I'll prefer a classic for:http://stackoverflow.com/questions/3156059/linq-statement-faster-than-foreach-loop – Massimiliano Peluso Sep 08 '11 at 15:04
  • @Yossarian please go at the link I have post on my previous comment and have a look at Marc Gravell answer – Massimiliano Peluso Sep 08 '11 at 15:13
  • Here is what Resharper spits out. var leiter = new List(); foreach (var mitarbeiter in mit) { var mitarbeiter1 = mitarbeiter; leiter.AddRange(from refs in refSchullung where refs.Id_person == mitarbeiter1.Id_mit select mitarbeiter1); } – Jeff Reddy Sep 08 '11 at 15:17
  • ...and don't forget debugging LINQ to object is really hard – Massimiliano Peluso Sep 09 '11 at 08:17
0

Using Join() would make a lot of sense in this case:

var joinQuery = mit.Join(refSchullung, x => x.Id_mit, x => x.Id_Person, (x, y) => x);
leiter.AddRange(joinQuery.ToList());

This will match up each element of the two sequences where the keys match, and select a single item for each case.

dlev
  • 48,024
  • 5
  • 125
  • 132