Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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
Linq,按IOrderedEnumerable排序一个IQueryable_Linq_Entity Framework_Telerik_Telerik Grid - Fatal编程技术网

Linq,按IOrderedEnumerable排序一个IQueryable

Linq,按IOrderedEnumerable排序一个IQueryable,linq,entity-framework,telerik,telerik-grid,Linq,Entity Framework,Telerik,Telerik Grid,我有一个MVC telerik网格,我已设置该网格,用于对IQueryable进行自定义绑定,以方便对计算列进行排序。根据此属性对网格进行排序时的默认排序行为如下: data = data.OrderBy(product => product.oneMthCost_IntOnly); “data”是IQueryable,product.oneMthCost_InOnly不是从数据库返回的,它是一个计算属性,在“SearchViewModel”上为此属性调用“get”访问器时计算得出: 为

我有一个MVC telerik网格,我已设置该网格,用于对IQueryable进行自定义绑定,以方便对计算列进行排序。根据此属性对网格进行排序时的默认排序行为如下:

data = data.OrderBy(product => product.oneMthCost_IntOnly);
“data”是IQueryable,product.oneMthCost_InOnly不是从数据库返回的,它是一个计算属性,在“SearchViewModel”上为此属性调用“get”访问器时计算得出:

为了解释如何返回SearchViewModel(“数据”),它基于一个实体数据模型,该实体数据模型使用以下延迟Linq查询作为网格投影到SearchViewModel的基础

    //Return the required products
    var model = from p in Product.Products
                where p.archive == false && ((Prod_ID == 0) || (p.ID == Prod_ID))
                select new SearchViewModel
                    {
                        ID = p.ID,
                        lend_name = p.Lender.lend_name,
                        pDes_rate = p.pDes_rate,
                        pDes_details = p.pDes_details,
                        pDes_totTerm = p.pDes_totTerm,
                        pDes_APR = p.pDes_APR,
                        pDes_revDesc = p.pDes_revDesc,
                        pMax_desc = p.pMax_desc,
                        dDipNeeded = p.dDipNeeded,
                        dAppNeeded = p.dAppNeeded
                    };
因此,使用轴网默认行为,可以执行以下操作:

var calcdata = data.ToList().OrderBy(p => p.oneMthCost_IntOnly);
calcdata = data.ToList().OrderByDescending(p => p.oneMthCost_IntOnly);
data=data.OrderBy(product=>product.CalculatedProp)

此列排序时引发此错误:

中不支持指定的类型成员“oneMthCost\u IntOnly” LINQ对实体的访问。仅初始值设定项、实体成员和实体 支持导航属性

这是有道理的,表达式树在使用“get”访问器获取该值之前不知道该值是什么。因此,我不得不接受这样一个事实:我需要具体化整个对象集,对每一行进行计算,然后对IQueryable进行排序(不幸的是,业务逻辑太复杂,表达式树无法将计算转换为SQL,因此需要C#方法)。因此,我做了以下工作:

var calcdata = data.ToList().OrderBy(p => p.oneMthCost_IntOnly);
calcdata = data.ToList().OrderByDescending(p => p.oneMthCost_IntOnly);
它具体化所有数据,进行所有计算,并将其排序为IORDerenumerable calcdata。。。问题是:

如何将“calcdata”加入到“data”中,以按IOrderedEnumerable“calcdata”的键对IQueryable数据进行排序?将网格重新绑定到“calcdata”会弄乱分页,但是,如果您认为这是最好的方法,我也可以遵循此路径。

抱歉,这有点冗长,我只是想包括很多信息,让你了解最全面的情况

谢谢


标记

好-这是一个相当高的层次,是对您的完整问题的简短回答

我们遇到了排序非常复杂的数据集的问题。像你一样,我们试图了解他们,但表现很糟糕。我们最后做的是在数据库中创建一个视图,其中包含我们需要排序的列。我们在实体模型中包含了这个视图,它的行为就像一个表(老实说,有一些警告)

一旦我们在EF模型中有了这个观点,我们就可以使用order by而不必具体化。视图还可以包含所需的联接

这种方法在很大程度上取决于您对数据库的控制,我很欣赏不是每个开发人员都能做到这一点。我们发现这种通用方法非常成功,特别是如果您能够以这样的方式构造视图,那么就有可能在视图上获得主键

若您不能将视图放入数据库中,那个么您可以使用实体框架构造,比如类似的效果。但是,它们有自己的约束-例如,不能再自动更新模型,可以将QueryView以外的任何内容连接到它们。我相信这是可行的,但是您需要直接修改EF模型xml来实现这一点

视图注意事项

我们不得不将存储的进程映射到视图。因为它是只读的,所以我们真的不想为插入而烦恼,但是当删除依赖实体时,我从视图中导出了一个delete。TBH-我们在这一点上入侵了它,并包括一个影响一行和这项工作的虚拟进程。但肯定有比这更好的答案

好的-比我开始写作时想象的要简短

编辑

如果要加入这两个集合,可以使用
join
关键字。由于一个来自数据库,另一个来自c#,因此它们都必须包含IEnumerables,即通过
ToList()
实现的EF查询和适当集合中的c#对象,即通用列表

那么语法可能是

var joinedCollections = from efItem in efCollection
                     join charpItem in charpCollection on csharpItem.CommonId equals efItem.CommonID
                     select select new {csharp.field1, efItem.field1};

当然,这是假设两个集合之间有一个公共键。此外,效率可能会很糟糕。

我对以下问题的看法是正确的:

var calcdata = data.ToList().OrderBy(p => p.oneMthCost_IntOnly);
calcdata = data.ToList().OrderByDescending(p => p.oneMthCost_IntOnly);
当以这种方式进行排序时,这会对所有数据行进行计量(我知道这不是很有效,但这是唯一能够对数据库不知道的数据进行排序的方法)。我遇到的问题是,在分页时,上面创建了一个IOrderedEnumerable,如下所示:

        //Then paging
        if (command.PageSize > 0)
        {
            calcdata = calcdata.Skip((command.Page - 1) * command.PageSize);
        }

        calcdata = calcdata.Take(command.PageSize);
这会发出一个IEnumerable back(我假设它会发出一个IORDerenumerable),因此我们试图回溯到这种类型,这会破坏分页。上述方法适用于calcdata是IEnumerable而不是IORDerenumerable的情况。IQueryable不需要任何连接(当您拥有所有所需信息时,为什么要返回数据库?),因此我们重新绑定到IEnumerable

谢谢你的意见,它引导我进行了一些新的调查,帮助我最终解决了这个问题

问候,


Mark

首先,感谢您的回复!我的问题是,数据库中没有存储这些数据,因为这个特定属性的计算考虑了产品的许多属性以及用户的输入。其中的问题在于,该列只能使用c#方法计算,因为业务逻辑相当复杂&它需要来自EDM和用户的数据。我想我可以在MS SQL中使用Scaler函数(我可以完全控制数据库,这很有用)。有没有关于Linq语法的想法,可以将“数据”和“calcdata”连接起来,这样我就可以返回数据?@MagicalArmchair。我补充了一些想法——我相信你已经考虑过了,因为你的知识对我来说似乎很深