1

For example. This table, I want to search items taged with 'c', not with 'c#' or 'c++'. Tags are seperated by a space.

ID  |  BookName              |  Tags 

1   |  C++ Primer            | c++ 
2   | .NET Core 3.1 Tutorial | c# .net
3   | Beginner Tutorial      | c c# c++

Each book record can be marked with multiple tags, If I use

dbContext.Book.Where(a => a.Tags.Contains("c")).ToList()

I'll get all of them. But I only want get Beginner Tutorial. Since I can not use = to filter the Tag field. How can I solve this?

PS: I can not change the structure of this table, either.

Selim Yildiz
  • 5,254
  • 6
  • 18
  • 28
wtf512
  • 4,487
  • 9
  • 33
  • 55

5 Answers5

2

You could Split the Tags Fields on delimiter (in your case whitespace) and verify if the tag is present. For example

var result = dbContext.Book.Where(a => a.Tags.Split(' ').Contains("c"));
Anu Viswan
  • 17,797
  • 2
  • 22
  • 51
2

You need to first Split Tags by whitespace then you can use Contains or Any

By doing this with Contains:

var result = dbContext.Book.Where(a => a.Tags.Split(' ').Contains("c"));

By doing this with Any:

var result = dbContext.Book.Where(a => a.Tags.Split(' ').Any(t => t.Equals("c")))

These will give you expected result.

You can also check difference-between-contains-and-any-in-linq

Selim Yildiz
  • 5,254
  • 6
  • 18
  • 28
  • wouldn't the contains become == instead, as `c#` contains c, and i don't think it should match on tag c#. aka tags = "php c# f#" should fail where as tags = "php c" should pass. – Seabizkit Dec 17 '19 at 13:33
1
var result = dbContext.Book.Where(a => a.Tags.Split(' ').Any(t => t.Equals("c")))
4b0
  • 21,981
  • 30
  • 95
  • 142
Lyuben
  • 13
  • 1
  • 3
0

You can do it by regex too.

Regex regex = new Regex(@"^c$| c|c ");
var result = books.Where(a => regex.Match(a.Tags).Success);
Furkan Öztürk
  • 1,178
  • 11
  • 24
0

Modify your model as follows :

public string Tags
    {
        get
        {
            return TagsList != null
                ? String.Join(" ", TagsList.Select(tag => tag ))
                : null;
        }
        set
        {
            TagsList = !String.IsNullOrWhiteSpace(value)
                ? value.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList()
                : new List<string>();
        }
    }

[NotMapped]
public List<string> TagsList { get; set; }

Then use :

dbContext.Books.Where(a=>a.TagsList.Contains("c"));
Xueli Chen
  • 11,987
  • 3
  • 25
  • 36