Как использовать LINQ и PredicateBuilder для создания предиката с использованием подкласса?

Я пытаюсь использовать этот ответ для динамического добавления оператора ИЛИ к предложению WHERE в LINQ: /questions/15796060/kak-dinamicheski-dobavit-operator-or-v-predlozhenie-where-v-linq/15796064#15796064

var searchPredicate = PredicateBuilder.False<Songs>();

foreach(string str in strArray)
{
    var closureVariable = str;
    searchPredicate = 
     searchPredicate.Or(SongsVar => SongsVar.Tags.Contains(closureVariable));
}

var allSongMatches = db.Songs.Where(searchPredicate);

В моем случае Теги - это List, а не свойство, я хотел бы сделать что-то вроде этого:

searchPredicate.Or(SongsVar => SongsVar.Tags.Any().TagName.Contains(closureVariable));

Затем я подумал о чем-то таком, что не работает:

searchPredicate.Or(x => x.Tags.Where(p => p.TagName.Contains(closureVariable )).Count() > 0);

Это возможно?

1 ответ

Решение

Да, это должно быть возможно:

  var searchPredicate = PredicateBuilder.False<Songs>();

  var strArray = new[] {"aa", "bb"};

  foreach (string str in strArray) {
    var closureVariable = str;
    searchPredicate =
     searchPredicate.Or(songsVar => songsVar.Tags.Any(tagVar => tagVar.TagName == closureVariable));
  }

  var songs = new List<Songs> {
    new Songs {Tags = new List<Tag> {new Tag {TagName = "aa"}}},
    new Songs {Tags = new List<Tag> {new Tag {TagName = "bb"}}},
    new Songs {Tags = new List<Tag> {new Tag {TagName = "aa"}, new Tag {TagName = "cc"}}},
    new Songs {Tags = new List<Tag> {new Tag {TagName = "cc"}, new Tag {TagName = "dd"}}}
  };

  var res = songs.Where(searchPredicate.Compile());

С Songs а также Tag определяется как:

  public class Songs {
    public List<Tag> Tags { get; set; }
  }

  public class Tag {
    public string TagName { get; set; }
  }

Затем, res содержит первые 3 записи, определенные в songs как и ожидалось.

Другие вопросы по тегам