Linq与可选的WHERE选项

问题描述:

我有一个.Net函数,接受3个参数,全部可选。事情是这样的:Linq与可选的WHERE选项

public List<MyObject> Search(string colour, string size, string name) 
{ 
    var result = (from c in MyTable where .... select c).ToList();  
} 

我的问题是,什么是应该做的where部分的最佳方式。最好是创建动态linq?在LINQ中,什么是最好的模式,可以选择参数?

所以,在SQL中,这样的事情:

SELECT * 
FROM MyTable 
WHERE (@colour <> '' AND colour = @colour) 
    AND (@size <> '' AND size = @size) 
    AND (@name <> '' AND name = @name) 

但我希望有对LINQ内这样做更整洁,更可以接受的模式。

+0

你可以用'Expression's或一些第三部分动态的LINQ库。 –

简单的连锁Where条款对于空

检查
var result = context.MyTable 
        .Where(t => color == null || color == t.Color) 
        .Where(t => size == null || size == t.Size) 
        .Where(t => name == null || name == t.Name) 
        .ToList() 

你可以做这样的事情在你的Search方法如下:

var query = from c in MyTable select c; 
if (!String.IsNullOrEmpty(colour)) 
    query = from c in query where c.colour == colour select c; 
if (!String.IsNullOrEmpty(size)) 
    query = from c in query where c.size == size select c; 
if (!String.IsNullOrEmpty(name)) 
    query = from c in query where c.name == name select c; 
return query.ToList(); 

如何:

public List<MyObject> Search(string colour, string size, string name) 
{ 
    IEnumerable<MyObject> result = MyTable; 

    if(colour != null) 
     result = result.Where(o => o.Colour == colour); 

    if(size != null) 
     result = result.Where(o => o.Size == size); 

    ... 

    return result.ToList(); 
} 

var results = olstOfObjects.Where(x => 
    (x.size == size || x.size == "") && 
    (x.color == color || x.color == "") && 
    (x.name == name || x.name == "")).ToList(); 

在这种情况下,我会建议你使用PredicateBuilder产生您的查询。您可以从这里复制代码,或者您可以安装LinqKit Nuget Package。

使用此代码将允许您即时生成动态查询,并防止您编写大量的if/else语句。

之类的语句...

p => p.Price > 100 && 
p.Price < 1000 && 
(p.Description.Contains ("foo") || p.Description.Contains ("far")) 

将这种代码生成:

var inner = PredicateBuilder.False<Product>(); 
inner = inner.Or (p => p.Description.Contains ("foo")); 
inner = inner.Or (p => p.Description.Contains ("far")); 

var outer = PredicateBuilder.True<Product>(); 
outer = outer.And (p => p.Price > 100); 
outer = outer.And (p => p.Price < 1000); 
outer = outer.And (inner); 

我认为这是相当整洁,它也会给你如何强大的表达式的理解可。

在这里你有1个查询与所有条件:

public List<object> Search(string colour, string size, string name) 
{ 
    var query = from c in MyTable 
     where 
      (string.IsNullOrEmpty(colour) || c.colour == colour) && 
      (string.IsNullOrEmpty(size) || c.size == size) && 
      (string.IsNullOrEmpty(name) || c.name == name) 
     select c; 

    return query.ToList(); 
}