Tun
Tun

Reputation: 912

Linq (EF) where clause with string comma seperated

I have C# Lambda linq query as follow:

public IQueryable<CtArticleDetail> GetArticleDetailsByTagNames(string tagNames)
{
    return db.CtArticleTags.Where(m => tagNames.Contains(m.CtTag.Name) 
                                       && m.CtArticleDetail.ExpirationDate > DateTime.Now
                                       && m.CtArticleDetail.ArticleStatusId == (int)ArticleStatus.Published)
                           .Select(m => m.CtArticleDetail).OrderBy(x => x.LiveDate).Distinct();
}

This returns slightly wrong data list because of "Contains". The parameter actually comes this format: EG ( "AterSale,GeneralSale"). The result list contains other sale type articles.EG ("Sale" or "ImportedSale").

The reuslt list should be exact list as parameter passed. Can anyone pls advice ?

var mustContain = new[] {"A", "B");

var foos = new  List<Foo>(){
     new Foo1 {Tags = "A"},
     new Foo1 {Tags = "B"},
     new Foo2 {Tags = "A"},
     new Foo2 {Tags = "C"}
};   

I just need Foo1 if mustcontain is A,B

Upvotes: 0

Views: 2278

Answers (1)

Tim Schmelter
Tim Schmelter

Reputation: 460238

If i understand you correctly tagNames is a string which is a list of tagNames separated by comma. Then you could use String.Split:

String[] tags = tagNames.Split(new[]{","}, StringSplitOptions.RemoveEmptyEntries);
return db.CtArticleTags.Where(m => tags.Contains(m.CtTag.Name) && m.CtArticleDetail.ExpirationDate > DateTime.Now
            && m.CtArticleDetail.ArticleStatusId == (int)ArticleStatus.Published)
            .Select(m => m.CtArticleDetail).OrderBy(x => x.LiveDate).Distinct();

According to your comment

What about If I need multiple condition. EG. Let say - 'tags' contains sale,aftersale. I like to retrieve that article must have SALE and AFTERSALE tagged. Not only SALE or AFTERSALE

You can use Enumerable.All, here's a Linq-To-Objects example which you can hopefully convert to Linq-To-Entities:

var mustContain = new[] { "A", "B" };
var foos = new List<Foo>() { 
    new Foo{Tags="A,B"},
    new Foo{Tags="B"},
    new Foo{Tags="C,A"},
    new Foo{Tags="D"},
    new Foo{Tags="B,A,C"},
    new Foo{Tags="F,C,A,D,B"},
};

var result = foos
    .Where(f => mustContain.All(mc =>  
        f.Tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
              .Contains(mc))); 

Upvotes: 1

Related Questions