Linq(EF)where子句用逗号分隔

时间:2012-10-17 10:29:50

标签: c# linq entity-framework-4 lambda

我有C#Lambda linq查询如下:

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();
}

由于“Contains”,这会返回稍微错误的数据列表。该参数实际上是这种格式:EG(“AterSale,GeneralSale”)。结果列表包含其他销售类型文章.EG(“Sale”或“ImportedSale”)。

当传递参数时,reuslt列表应该是精确列表。任何人都可以提出建议吗?

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"}
};   

如果必须是A,B,我只需要Foo1

1 个答案:

答案 0 :(得分:1)

如果我理解正确tagNames是一个字符串,它是由逗号分隔的tagNames列表。然后你可以使用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();

根据你的评论

  

如果我需要多个条件怎么办?例如。让我们说 - 'tags'包含   售中,售后。我想要检索那篇文章必须有SALE和   AFTERSALE已标记。不仅销售或售后

您可以使用Enumerable.All,这是一个Linq-To-Objects示例,您可以将其转换为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)));