0

I have the following code:

var translations = _context.Translations
       Where(t => t.LineId == lines.Id)

I got a variable named lines which is of type List<Line> every Line object has Line.Id

Now I have another table named Translations I would like to get all Translations which have Line.Id that is equal to every Line.Id from the lines list.

How can I accomplish this in a single LINQ expression?

I need something like this:

 var translations = new List<Translation>();

 foreach (var line in lines)
 {
    var translation =
    _context.Translations.FirstOrDefault(t => t.LineId == line.Id);
    translations.Add(translation);
 }
Drago
  • 1,755
  • 3
  • 19
  • 30
  • What you are asking for is puzzling. "Which have `Line.Id` that is equal to every `Line.Id` from the `lines` list" implies that all the `Line.Id` values in `lines` are exactly the same. Is that the case? If so, you are looking for `IEnumerable.All()`. If it's not, and you want to return translations that match any ID in `lines`, you want `IEnumerable.Any()`. – Mike Hofer Jun 30 '22 at 20:19
  • @MikeHofer neither of those, I only want translations for those ids found in `lines` . – Drago Jun 30 '22 at 20:23
  • I added an example of what I want. – Drago Jun 30 '22 at 20:28

2 Answers2

1

Project an IEnumerable<T> of your Line.Id property, then use the result in your query with the Contains method:

var lineIDs = lines.Select(l => l.Id).ToArray();

var translations = _context.Translations
    .Where(t => lineIDs.Contains(t.LineId))
    .ToList();
Moho
  • 15,457
  • 1
  • 30
  • 31
0

Since you want only those translations that have IDs that exist in lines, this will get you what you want:

var translations = from translation in _context.Translations
                   join line in lines on translation.LineID equals line.LineID
                   select translation;

A join will be faster than invoking a LINQ query for each item in the Translations "table."

Mike Hofer
  • 16,477
  • 11
  • 74
  • 110
  • This would be evaluated client side, thus returning all `Translation` entities from the DB/data source, no? – Moho Jun 30 '22 at 20:32
  • Not entirely. Only those with matching rows in the lines table will be returned. But he's made no indication that's using stored procedures, and he's asking for a LINQ-based solution. This one implements an INNER JOIN between the two sequences, avoiding the need to iterate over one sequence, and, for each element, iterate over the second sequence. – Mike Hofer Jun 30 '22 at 20:40
  • @Moho LINQ Joins are almost always faster than a where. See this SO question: https://stackoverflow.com/questions/5551264/why-is-linq-join-so-much-faster-than-linking-with-where. – Mike Hofer Jun 30 '22 at 20:43
  • `lines` is not a table, it's a local `List`. Unless something has changed in EF relatively recently, this would be evaluated client side, thus `Contains` in a `Where` predicate is the correct method to minimize data transfer and object construction in the client. I would appreciate being pointed in the correct direction if I am incorrect. – Moho Jun 30 '22 at 21:05