我想使用List
过滤Linq Where / Select
,使用Dictionary
中的键值,如程序中所示,我当前的解决方案有许多限制。
Dictionary
指的是来自UI的用户输入,因此它可能包含一组值而不是给定键的单个值。
任何帮助我找到正确方向的指针。
public class Business
{
public int ID { get; set; }
public string NAME { get; set; }
}
void Main()
{
var businessList = new List<Business>
{
new Business {ID = 1,NAME = "A"},
new Business {ID = 1,NAME = "B"},
new Business {ID = 1,NAME = "C"},
new Business {ID = 2,NAME = "D"},
new Business {ID = 2,NAME = "E"},
new Business {ID = 2,NAME = "F"},
new Business {ID = 3,NAME = "G"},
new Business {ID = 4,NAME = "H"},
new Business {ID = 4,NAME = "I"},
new Business {ID = 4,NAME = "J"},
new Business {ID = 5,NAME = "K"},
new Business {ID = 5,NAME = "L"}
};
var filterDictionary = new Dictionary<string, object>
{
{"ID",3},
{"NAME","G"}
};
Expected Result:
ID Name
3 G
var filterDictionary = new Dictionary<string, object>
{
{"ID",new List<int>(){2,3}}
};
Expected Result:
ID Name
2 D
2 E
2 F
3 G
Current Solution:
var result = businessList
.Select(x => filterDictionary.ContainsKey(typeof(Business).GetProperty("ID").Name) ?
x.ID == (int)filterDictionary[typeof(Business).GetProperty("ID").Name] ? x : null : null
)
.Where(x => x!= null)
.Select(x => filterDictionary.ContainsKey(typeof(Business).GetProperty("NAME").Name) ?
x.NAME == (string)filterDictionary[typeof(Business).GetProperty("NAME").Name] ? x : null : null
);
}
答案 0 :(得分:3)
这是一个解决方案:
//Calculate valid IDs from the dictionary
List<int> valid_ids =
filterDictionary
.Where(x => x.Key == "ID")
.SelectMany(x =>
{
if (x.Value is int)
{
return new[] {(int) x.Value};
}
return (IEnumerable<int>) x.Value;
}).ToList();
//Calculate valid NAMEs from the dictionary
List<string> valid_names =
filterDictionary
.Where(x => x.Key == "NAME")
.SelectMany(x =>
{
if (x.Value is string)
{
return new[] { (string)x.Value };
}
return (IEnumerable<string>)x.Value;
}).ToList();
IEnumerable<Business> query = businessList;
if (valid_ids.Count > 0)
query = query.Where(x => valid_ids.Contains(x.ID));
if(valid_names.Count > 0)
query = query.Where(x => valid_names.Contains(x.NAME));
var result = query.ToList();
答案 1 :(得分:1)
执行此操作的一般方法是使用反射和缓存属性GetMethod来提高性能,因为反射可能非常慢。您还可以使用泛型,以便它可以使用任何类型。以下可能是您正在寻找的东西。
private static List<T> FilterList<T>( IEnumerable<T> source, Dictionary<string, object> propertyFilters )
{
var properties = propertyFilters.Keys.Distinct()
.ToDictionary( x => x, x => typeof ( T ).GetProperty( x ).GetGetMethod() );
IEnumerable<T> result = source.ToList();
foreach ( var propertyFilter in propertyFilters )
{
if ( properties.ContainsKey( propertyFilter.Key ) )
{
result = result.Where( x =>
{
var invoke = properties[propertyFilter.Key].Invoke( x, new object[0] );
if ( propertyFilter.Value is IList )
{
return ( (IList)propertyFilter.Value ).Cast<object>().Any( f =>
{
return f.Equals( invoke );
} );
}
return invoke.Equals( propertyFilter.Value );
} );
}
}
return result.ToList();
}
答案 2 :(得分:0)
以下是我的解决方案(返回预期结果):
var result = businessList.Where(bl => filterDictionary
.Count(fd => bl.GetType().GetProperty(fd.Key).GetValue(bl, null) == fd.Value) > 0);
答案 3 :(得分:-1)
字典只能有唯一的密钥。如果您拥有相同的密钥不止一次,则密钥的值必须是集合。见下面的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Business> businessList = new List<Business>
{
new Business {ID = 1,NAME = "A"},
new Business {ID = 1,NAME = "B"},
new Business {ID = 1,NAME = "C"},
new Business {ID = 2,NAME = "D"},
new Business {ID = 2,NAME = "E"},
new Business {ID = 2,NAME = "F"},
new Business {ID = 3,NAME = "G"},
new Business {ID = 4,NAME = "H"},
new Business {ID = 4,NAME = "I"},
new Business {ID = 4,NAME = "J"},
new Business {ID = 5,NAME = "K"},
new Business {ID = 5,NAME = "L"}
};
Dictionary<int, List<string>> dict = businessList.AsEnumerable()
.GroupBy(x => x.ID, y => y.NAME)
.ToDictionary(x => x.Key, y => y.ToList());
}
public class Business
{
public int ID { get; set; }
public string NAME { get; set; }
}
}
}