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

发布于 2024-10-30 09:45:59 字数 536 浏览 1 评论 0原文

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

我遇到的问题是,我使用 EF 4 和代码优先,并且我能找到的所有过滤都是使用 Linq 查询,但我不能查看一种根据用户选择的过滤器选项动态构建过滤器的 where 子句的方法。即在 SQL 中你可以构建,

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

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

编辑
我要尝试的解决方案类似于使用 LINQ 实现动态搜索。因为我更喜欢尽可能通用。

I have started using the entity framework for a web application and would like to know what the best way would be to allow users to filter lists dynamically.
i.e. If we have a list of people the user can filter by lastname, city, etc.

The problem I am having is that I am using EF 4 with code first and all the fitlering I can find is using Linq queries but I can't see a way to build up the where clause for the filter dymaically based on the filter options the user has selected. i.e. in SQL you could build,

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

Is there a way to build up this list dynamically using linq?

EDIT
The solution I'm going to try will be similar to this Implementing Dynamic Searching Using LINQ. As I prefer to be as generic as possible where I can.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

送你一个梦 2024-11-06 09:45:59

例如,执行此操作的方法是为搜索条件定义某种类型:

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

并为 IQueryable 定义自定义扩展方法:

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

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

The way to do this is for example defining some type for search criteria:

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

and define custom extension method for 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;
}

Now you only need to create model binder (or use default one if possible) to fill your serach options to PeopleSearchCriteria instance and execute simply:

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

If you really want some dynamic approach you can build expression tree manually or check Dynamic Linq (you will lose compile time checks).

稀香 2024-11-06 09:45:59

例如:
这可以让你过滤人员的集合。

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

For example:
This gets you filtered collection of people.

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

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

If you want to return both entities in one collection, than you can do something like:

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

You will get collection of objects and you will be able to access them like:

foreach (var item in myCollection)
{
  var personName = item.person.lastname;
  var cityAddress = item.address.city;
}
離人涙 2024-11-06 09:45:59

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

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

I am suggesting to use repository pattern for such kind of things

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

here is an example;

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

  }
}

and after that you can use them outside of your class easily. like below;

PeopleRepository _repo = new PeopleRepository();

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

you mentioned that you want the parameters as user input. I do not know where you will use your entity model (asp.net web forms, win forms or asp.net mvc), but here is an example of that;

PeopleRepository _repo = new PeopleRepository();

DataList1.DataSource =  _repo.GetAll(LastnameTextBox.Text, CityTextBox.Text);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文