2011-04-03 66 views
1

我已经开始使用Web应用程序的实体框架,并希望知道允许用户动态过滤列表的最佳方式是什么。 即如果我们有一个人的名单,用户可以过滤姓氏,城市等实体框架4带过滤器的通用列表方法

我遇到的问题是,我使用EF 4与代码第一和所有fitlering我可以找到使用Linq查询但我不能看到一种方法来基于用户选择的过滤器选项以动态方式构建过滤器的where子句。即在你可以建立的SQL,

select * from people, address where lastname = 'jones' and address.city = 'sydney' 

有没有办法使用linq动态建立这个列表?

编辑
的解决方案,我要去尝试将类似于此Implementing Dynamic Searching Using LINQ。因为我希望尽可能通用。

回答

3

要做到这一点,例如定义一些类型的搜索条件的方式:

public class PeopleSearchCriteria 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string City { get; set; } 
} 

,并定义自定义扩展方法IQueryable<Person>

public static IQueryable<Person> FilterBySearchCriteria(this IQueryable<Person> query, 
    PeoplseSearchCritera criteria) 
{ 
    if (!String.IsNullOrEmpty(criteria.FirstName)) 
    { 
     string firstName = criteria.FirstName; 
     query = query.Where(p => p.FirstName == firstName); 
    } 

    // do similar code for other criterias 

    return query; 
} 

现在你只需要创建模型联编程序(如果可能,使用默认值)将您的serach选项填充到PeopleSearchCriteria实例并简单执行:

var data = context.People.FilterBySearchCriteria(searchCriteria).ToList(); 

如果您真的想要一些动态方法,您可以手动构建表达式树或检查Dynamic Linq(您将失去编译时检查)。

+0

谢谢你应该工作,你的建议和动态LINQ之间有一个性能差异? – eaglestorm 2011-04-03 12:11:24

+0

我不确定这个soultion和动态linq有多大的区别。据我所知动态linq在内部使用'Reflection.Emit',但我从未测量过它的使用情况。 – 2011-04-03 12:23:11

0

例如:
这会让您过滤收集的人。

var people = EfDBContextEntities.people; // depends on your context and naming 

var filteredPeople = 
from p in people 
where p.lastname == "jones" 
select p; 

如果你想在一个集合中返回两个实体,比你可以这样做:

var myCollection = 
from p in people 
from a in address 
where p.lastname == "jones" 
where a.city == "sydney" 
select new {person = p, address = a}; 

您将获得对象的集合,你将能够访问他们喜欢的:

foreach (var item in myCollection) 
{ 
    var personName = item.person.lastname; 
    var cityAddress = item.address.city; 
} 
+0

我认为你错过了一点,我想基于用户输入建立查询的where部分,而不是硬编码。 – eaglestorm 2011-04-03 11:53:33

+0

您希望用户选择要查询哪些列或仅筛选哪些值? – Damb 2011-04-03 12:11:57

0

我建议使用存储库模式对于此类事情

http://msdn.microsoft.com/en-us/library/ff649690.aspx

这里是一个例子;

public class PeopleRepository { 

    HumanEntities _entities = new HumanEntities(); 

    public IQueryable<people> GetAll() { 

    IQueryable<people> query = _entities.Customers; 

    retun query; 

    } 

    public IQueryable<people> GetAll(string _lastname, string _city) { 

    //I am thinking that people and address tables are related to each other 
    //as one to many or many to many. So the example should look like below; 
    var query = GetAll().Where(x => x.lastname = _lastname && x.address.city = _city); 

    retun query; 

    } 

    public void Save() { 

    _entities.SaveChages() 

    } 
} 

之后,您可以轻松地在课堂之外使用它们。像下面一样;

PeopleRepository _repo = new PeopleRepository(); 

DataList1.DataSource = _repo.GetAll("ugurlu", "LA"); 

你提到你需要参数作为用户输入。我不知道你会在哪里使用你的实体模型(asp.net web窗体,win窗体或asp.net mvc),但这里是一个例子;

PeopleRepository _repo = new PeopleRepository(); 

DataList1.DataSource = _repo.GetAll(LastnameTextBox.Text, CityTextBox.Text);