Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 动态LINQ是否仍在使用,是否适合缩小搜索结果的范围?_Asp.net Mvc 3_Linq_Filtering_Dynamic Linq - Fatal编程技术网

Asp.net mvc 3 动态LINQ是否仍在使用,是否适合缩小搜索结果的范围?

Asp.net mvc 3 动态LINQ是否仍在使用,是否适合缩小搜索结果的范围?,asp.net-mvc-3,linq,filtering,dynamic-linq,Asp.net Mvc 3,Linq,Filtering,Dynamic Linq,我正在用C#开发一个ASP.NET MVC3应用程序 我试图在我的应用程序中实现一个应用于搜索结果集的“缩小”功能 简言之,在执行搜索并将结果显示在页面中心后,我希望在页面的左/右侧为搜索结果的每个属性设置一个复选框列表帮助程序。每个复选框列表的复选框表示属性的不同值 例如,如果我搜索产品,它有一个值为蓝色、红色和黄色的颜色属性,我将创建一个复选框列表,其中包含文本颜色,以及三个复选框-为每种颜色创建一个 在对Web进行研究后,我发现Scott Guthrie提供了这个动态LINQ库。因为我发现

我正在用C#开发一个ASP.NET MVC3应用程序

我试图在我的应用程序中实现一个应用于搜索结果集的“缩小”功能

简言之,在执行搜索并将结果显示在页面中心后,我希望在页面的左/右侧为搜索结果的每个属性设置一个
复选框列表
帮助程序。每个
复选框列表的
复选框
表示属性的不同值

例如,如果我搜索
产品
,它有一个值为蓝色、红色和黄色的
颜色
属性,我将创建一个
复选框列表
,其中包含文本颜色,以及三个
复选框
-为每种颜色创建一个

在对Web进行研究后,我发现Scott Guthrie提供了这个动态LINQ库。因为我发现的最新示例/教程是2009年的,所以我想知道这个库是否真的很好(并得到了维护)


在后一种情况下,jQuery是实现此类功能的最佳方式吗?

我真的不明白为什么您需要动态LINQ?项目属性在编译时未知吗?如果可以通过名称访问给定的项目属性,例如,
var prop=myitem['Color']
,则不需要动态LINQ

这取决于渲染结果的方式。一般来说,有很多方法可以实现所需的行为:

  • 完全客户端。如果您在客户端执行所有操作(获取数据、渲染、分页),jQuery将是最好的方法
  • 服务器端+客户端。如果在服务器上呈现结果,则可以向每个搜索结果标记中添加HTML属性(针对每个属性),并过滤这些客户端。这种情况下唯一的问题可能是分页(如果在服务器端进行分页,则只能筛选当前页面)
  • 完全服务器端。使用搜索参数发布表单,并使用LINQ缩小搜索结果范围-将现有项的属性与表单值匹配
  • 编辑

    如果我是你(并且需要在服务器端过滤结果),我会做如下操作:

        var filtered = myItems.Where(i => i.Properties.Match(formValues))
    
    其中
    Match
    是一种扩展方法,用于检查给定的属性列表是否与提供的值匹配。如此简单-不需要动态LINQ

    编辑2


    是否需要将LINQ查询映射到数据库查询(LINQ到SQL)?这会使事情复杂一些,但通过链接多个
    .Where(…)
    子句仍然是可行的。只需在过滤器属性上循环并将
    。其中(…)
    添加到上一次迭代的查询中。

    简而言之,您可以从C#4.0的作者那里了解一下,正如@Piotr Szmyd已经指出的那样,您可能不需要动态Linq。迭代T的所有属性不需要动态linq。动态Linq主要用于在客户端构建完整的查询,并将其以字符串格式发送到服务器。 但是现在,它已经过时了,因为MVC4支持通过返回IQueryable的Api控制器进行客户端查询。 如果您只需要迭代T的所有属性,那么可以通过反射和构建将构成过滤条件的LambdaExpressions来完成。您可以使用的静态方法来完成。
    通过使用此类静态方法,您可以使用两条指令动态构建m=>m.Name=“Nick”之类的表达式……然后输入它们……得到的表达式可以应用于现有IQueryable

    您可以通过纯粹使用.NET framework动态构建所需的谓词表达式来解决此问题

    请参阅下面的代码示例。根据条件,这将根据多个特性进行过滤。我之所以使用IQuerable,是因为这将在内存中启用这两种远程场景,例如实体框架。如果使用实体框架,还可以动态构建EntitySQL字符串。我希望这会表现得更好

    涉及到一小部分反射(GetProperty)。但这可以通过在BuildPredicate方法中执行缓存来改进

    public class Item
    {
        public string Color { get; set; }
        public int Value { get; set; }
        public string Category { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var list = new List<Item>()
            {
                new Item (){ Category = "Big", Color = "Blue", Value = 5 },
                new Item (){ Category = "Small", Color = "Red", Value = 5 },
                new Item (){ Category = "Big", Color = "Green", Value = 6 },
            };
    
            var criteria = new Dictionary<string, object>();
            criteria["Category"] = "Big";
            criteria["Value"] = 5;
    
            var query = DoDynamicWhere(list.AsQueryable(), criteria);
            var result = query.ToList();
        }
    
        static IQueryable<T> DoDynamicWhere<T>(IQueryable<T> list, Dictionary<string, object> criteria)
        {
            var temp = list;
    
            //create a predicate for each supplied criterium and filter on it.
            foreach (var key in criteria.Keys)
            {
                temp = temp.Where(BuildPredicate<T>(key, criteria[key]));
            }
    
            return temp;
        }
    
        //Create i.<prop> == <value> dynamically
        static Expression<Func<TType, bool>> BuildPredicate<TType>(string property, object value)
        {
            var itemParameter = Expression.Parameter(typeof(TType), "i");
    
            var expression = Expression.Lambda<Func<TType, bool>>(
                Expression.Equal(
                    Expression.MakeMemberAccess(
                        itemParameter,
                        typeof(TType).GetProperty(property)),
                    Expression.Constant(value)
                ),
                itemParameter);
    
            return expression;
        }
    }
    
    公共类项目
    {
    公共字符串颜色{get;set;}
    公共int值{get;set;}
    公共字符串类别{get;set;}
    }
    班级计划
    {
    静态void Main(字符串[]参数)
    {
    var list=新列表()
    {
    新项目(){Category=“Big”,Color=“Blue”,Value=5},
    新项目(){Category=“Small”,Color=“Red”,Value=5},
    新项目(){Category=“Big”,Color=“Green”,Value=6},
    };
    var条件=新字典();
    标准[“类别”]=“大”;
    标准[“值”]=5;
    var query=DoDynamicWhere(list.AsQueryable(),条件);
    var result=query.ToList();
    }
    静态IQueryable DoDynamicWhere(IQueryable列表、字典标准)
    {
    var-temp=列表;
    //为每个提供的标准创建一个谓词并对其进行筛选。
    foreach(var-key-in-criteria.key)
    {
    temp=temp.Where(BuildPredicate(key,criteria[key]);
    }
    返回温度;
    }
    //创建i.==动态
    静态表达式BuildPredicate(字符串属性、对象值)
    {
    var itemParameter=Expression.Parameter(typeof(TType),“i”);
    var expression=expression.Lambda(
    表达式。相等(
    Expression.MakeMemberAccess(
    itemParameter,
    typeof(TType).GetProperty(property)),
    表达式.常量(值)
    ),
    项目参数);
    返回表达式;
    }
    }
    
    LINQ实现仍然没有改变,因此应该有