【问题标题】:entity framework 4 generic list method with filters带有过滤器的实体框架 4 通用列表方法
【发布时间】:2011-04-05 11:44:03
【问题描述】:

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

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

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

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

编辑
我要尝试的解决方案将类似于Implementing Dynamic Searching Using LINQ。因为我更喜欢尽可能通用。

【问题讨论】:

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


    【解决方案1】:

    这样做的方法是,例如为搜索条件定义某种类型:

    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(您将失去编译时检查)。

    【讨论】:

    • 谢谢,应该可以,您的建议和动态 linq 之间是否存在性能差异?
    • 我不确定这个灵魂和动态 linq 之间会有多大的区别。据我所知,Dynamic linq 在内部使用 Reflection.Emit,但我从未测量过它对使用的任何影响。
    【解决方案2】:

    例如:
    这将为您提供过滤后的人员集合。

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

    【讨论】:

    • 我认为您忽略了一点,因为我想根据用户输入构建查询的 where 部分,而不是对其进行硬编码。
    • 您希望用户选择要查询哪些列或过滤哪些值?
    【解决方案3】:

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

    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 forms、win forms或asp.net mvc),但这里有一个例子;

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多