实体框架4带过滤器的通用列表方法

时间:2011-04-03 11:23:57

标签: .net asp.net-mvc entity-framework-4

我已经开始将实体框架用于Web应用程序,并想知道允许用户动态过滤列表的最佳方法。 即如果我们有一个人员列表,则用户可以按姓氏,城市等进行过滤

我遇到的问题是我首先使用带有代码的EF 4,并且我能找到的所有fitlering都使用Linq查询但是我看不到基于以下方式为过滤器构建过滤器的where子句的方法用户选择的过滤器选项。即在SQL中你可以构建,

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

有没有办法使用linq动态构建此列表?

修改
我要尝试的解决方案与此Implementing Dynamic Searching Using LINQ类似。因为我喜欢尽可能地尽可能通用。

3 个答案:

答案 0 :(得分: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;
}

现在您只需要创建模型绑定器(或者如果可能,使用默认绑定器)将您的搜索选项填充到PeopleSearchCriteria实例并执行简单:

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

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

答案 1 :(得分: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;
}

答案 2 :(得分: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);