GVKun编程网logo

asp.net – 可以手动将OData参数应用于`.AsQueryable()`的结果?

13

对于想了解asp.net–可以手动将OData参数应用于`.AsQueryable()`的结果?的读者,本文将是一篇不可错过的文章,并且为您提供关于.NETCore-IEnumerable与IQuer

对于想了解asp.net – 可以手动将OData参数应用于`.AsQueryable()`的结果?的读者,本文将是一篇不可错过的文章,并且为您提供关于.NET Core - IEnumerable 与 IQueryable 中产生的不同空间/地理结果、.net 手动建DataTable 获取DataTable列名 修改DataTable 列的顺序、.ToList()、.AsEnumerable()、AsQueryable() 之间有什么区别?、Asp.net MVC 中利用jquery datatables 实现数据分页显示功能的有价值信息。

本文目录一览:

asp.net – 可以手动将OData参数应用于`.AsQueryable()`的结果?

asp.net – 可以手动将OData参数应用于`.AsQueryable()`的结果?

我有一个返回IQueryable的MVC4 WebAPI控制器,因此我可以在URL中使用$filter和friends来操作REST端点的结果.这是我的控制器:

public class EnrollmentController : ApiController
{
    [Queryable]
    public IQueryable<tblEnrollment> Get()
    {
        var context = new ProjectEntities();
        context.ContextOptions.LazyLoadingEnabled = false;
        return context.tblEnrollment.AsQueryable();
    }
}

但是,就像this poster一样,我想让JSON输出格式略有不同,以便与Ember Data的预期格式更友好.所以我想回复一下:

return new { enrollment = context.tblEnrollment.AsQueryable() };

但是,这会破坏OData功能,因为我没有将IQueryable返回到WebAPI层.所以,我想知道是否有办法做这样的事情:

return new { enrollment = context.tblEnrollment.AsQueryable().ApplyOData() };

我肯定会成为真正的好方法……但是有没有办法根据IQueryable显式处理OData参数而不是让WebAPI层在Get方法返回的结果集上隐式执行它?还是有另一种方法可以实现我想要的东西吗?

顺便说一句,我暂时停留在EF4上,因为我无法升级到VS2012(因此无法升级到.NET4.5,因此也升级到EF5).理论上我可以升级到EF 4.3.1,如果有帮助的话.

解决方法

您可以添加ODataQueryOptions类型的参数并手动应用,而不是将您的操作标记为[可查询].这是它的样子:

public class EnrollmentController : ApiController
{
    public object Get(ODataQueryOptions<tblEnrollment> query)
    {
        var context = new ProjectEntities();
        context.ContextOptions.LazyLoadingEnabled = false;
        var queryResults = query.ApplyTo(context.tblEnrollment.AsQueryable());
        return new { enrollment = queryResults };
    }
}

.NET Core - IEnumerable 与 IQueryable 中产生的不同空间/地理结果

.NET Core - IEnumerable 与 IQueryable 中产生的不同空间/地理结果

如何解决.NET Core - IEnumerable 与 IQueryable 中产生的不同空间/地理结果?

我们将 ASP.NET Core 5 后端与 sql Server v15 和实体框架 V5 一起使用,有一些有趣的东西我一直在努力,考虑一下:

您有一张如下表格:

CREATE TABLE [dbo].[ContactDetails](
    [Id] [int] IDENTITY(1,1) NOT NULL,[Name] [nvarchar](128) NOT NULL,...
    [Geolocation] [geography] NULL
)

该表被其他表使用,例如。 Stores.,用于存储联系方式。

然后表 ContactDetails 会自动构建如下:

public partial class ContactDetail
{
    public ContactDetail()
    {
        Stores = new HashSet<Store>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public Geometry Geolocation { get; set; }
}    

然后你从输入中存储 Stores 的经度和纬度(双精度),比如:

Geometry Store.ContactDetails.Geolocation = new NetTopologySuite.Geometries.Point(store.longitude,store.latitude) { SRID = 4326 };

现在给定一个用户的位置,它是用同样的方式创建的

Geometry userLocation = new NetTopologySuite.Geometries.Point(user.longitude,user.latitude) { SRID = 4326 };

您想知道每个 Store 离用户有多远。你会怎么做?

我是这样做的:

DbContext dbContext; //...somehow constructed
var dbSet = dbContext.Set<Store>();
var distances = dbSet.Where(...).Select(store => store.ContactDetails.Geolocation.distance(userLocation));

但令我惊讶的是,距离完全消失了!我预计距离以度为单位返回,我将不得不将其转换为 Kms。但是这些数字完全不存在(比如 83130)。

所以我尝试了这个:

var anotherdistances = dbSet.Where(...).AsEnumerable().Select(store => store.ContactDetails.Geolocation.distance(userLocation));

这次的距离符合预期(例如 1.245 度)。

那里发生了什么? 我需要将结果保留为 IQueryable,以便我可以有效地进行进一步的过滤和转换。如何在不必将 IQueryable 转换为 IEnumerable 的情况下获得正确的距离?

我无法从其他问题中找到答案,我怀疑 Linq 无法将查询正确转换为 sql,并且 AsEnumerable() 之后的查询能够使用正确的类型推断并在加载时使用空间正确的方法内存中的对象。但这只是一些模糊的理解。如果您能帮助我理解这一点,我将不胜感激。

解决方法

您能否使用 IQuery<>.ToString() 来显示正在创建的实际 SQL 查询?也许这会为您指明正确的方向。另外,也许 this answer 很有趣。

此外,您可能需要查看您正在使用的数据库。根据{{​​3}}:

如果 EF Core 通过 SQL 对操作进行服务器评估,则结果为 单位由数据库决定。

,

好吧,谜团解开了。感谢 Dominik 的 @dominik-berse 建议,我进一步深入挖掘。

当查询从 LINQ 转换为 SQL 时,被映射的函数不必是等效的。在这种情况下,NetTopologySuite.Geometries.Distance() 被转换为 geography::STDistance() - 这取决于 SRID 模型的类型以不同的单位返回距离,在 4326 模型(由 GPS 使用)的情况下,它是米。>

当查询转换为对象时,将直接调用对象的方法,在本例中为 NetTopologySuite.Geometries.Distance()。

而且这两个值可以完全不同。

.net 手动建DataTable 获取DataTable列名 修改DataTable 列的顺序

.net 手动建DataTable 获取DataTable列名 修改DataTable 列的顺序

//创建 表
DataTable tables = new DataTable();
//添加 创建 列
//第一列
DataColumn cums = new DataColumn();
cums.ColumnName = "UserName";
cums.DataType = typeof(string);
tables.Columns.Add(cums);
cums = new DataColumn();
cums.ColumnName = "Age";
cums.DataType = typeof(string);
tables.Columns.Add(cums);
tables.Columns.Add("Address", typeof(string));  这种用的较多
tables.Columns["Address"].SetOrdinal(0);  //修改DataTable 列的顺序
string[] columnNames = GetColumnsByDataTable(tables);
string ss = columnNames[0];   
        /// <summary>
        /// 根据datatable获得列名
        /// </summary>
        /// <param name="dt">表对象</param>
        /// <returns>返回结果的数据列数组</returns>   
       public  string[] GetColumnsByDataTable(DataTable dt)
        {
            string[] strColumns = null;
            if (dt.Columns.Count > 0)
            {
                int columnNum = 0;
                columnNum = dt.Columns.Count;
                strColumns = new string[columnNum];
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    strColumns[i] = dt.Columns[i].ColumnName;
                }
            }
            return strColumns;
        }

.ToList()、.AsEnumerable()、AsQueryable() 之间有什么区别?

.ToList()、.AsEnumerable()、AsQueryable() 之间有什么区别?

IQueryable我知道第一个实现和第二个实现的 LINQ to Entities 和 LINQ to Objects
的一些区别,IEnumerable我的问题范围在 EF 5 内。

我的问题是这三种方法的技术差异是什么?我看到在许多情况下它们都有效。我还看到使用它们的组合,例如.ToList().AsQueryable().

  1. 这些方法到底是什么意思?

  2. 是否存在任何性能问题或会导致使用其中一个的问题?

  3. 例如,为什么要使用.ToList().AsQueryable()而不是.AsQueryable()

答案1

小编典典

关于这一点有很多话要说。让我重点关注AsEnumerable并一路AsQueryable提及。ToList()

这些方法有什么作用?

AsEnumerable并分别AsQueryable转换或转换为IEnumerableor 。IQueryable我说 强制转换或转换
是有原因的:

  • 当源对象已经实现了目标接口时,源对象本身被返回,但 被强制转换 为目标接口。换句话说:类型没有改变,但编译时类型改变了。

  • 当源对象没有实现目标接口时,源对象被 转换 成实现了目标接口的对象。所以类型和编译时类型都改变了。

让我用一些例子来说明这一点。我有这个报告编译时类型和对象的实际类型的小方法:

void ReportTypeProperties<T>(T obj){    Console.WriteLine("Compile-time type: {0}", typeof(T).Name);    Console.WriteLine("Actual type: {0}", obj.GetType().Name);}

让我们尝试一个任意的 linq-to-sql Table<T>,它实现IQueryable

ReportTypeProperties(context.Observations);ReportTypeProperties(context.Observations.AsEnumerable());ReportTypeProperties(context.Observations.AsQueryable());

结果:

Compile-time type: Table`1Actual type: Table`1Compile-time type: IEnumerable`1Actual type: Table`1Compile-time type: IQueryable`1Actual type: Table`1

您会看到表类本身总是被返回,但它的表示发生了变化。

现在是一个实现的对象IEnumerable,而不是IQueryable

var ints = new[] { 1, 2 };ReportTypeProperties(ints);ReportTypeProperties(ints.AsEnumerable());ReportTypeProperties(ints.AsQueryable());

结果:

Compile-time type: Int32[]Actual type: Int32[]Compile-time type: IEnumerable`1Actual type: Int32[]Compile-time type: IQueryable`1Actual type: EnumerableQuery`1

它在那里。AsQueryable()已将数组转换为EnumerableQuery,它“将IEnumerable<T>集合表示为IQueryable<T>数据源”。(MSDN)。

什么用途?

AsEnumerable 经常用于从任何IQueryable实现切换到 LINQ 到对象 (L2O),主要是因为前者不支持 L2O
具有的功能。

例如,在实体框架查询中,我们只能使用有限数量的方法。因此,例如,如果我们需要在查询中使用我们自己的方法之一,我们通常会编写类似

var query = context.Observations.Select(o => o.Id)                   .AsEnumerable().Select(x => MySuperSmartMethod(x))

ToList “将an转换IEnumerable<T>为a
List<T>”也经常用于此目的。使用AsEnumerablevs.的优点ToListAsEnumerable不执行查询。AsEnumerable保留延迟执行,并且不会构建通常无用的中间列表。

另一方面,当需要强制执行 LINQ 查询时,ToList可能是一种方法。

AsQueryable 可用于使可枚举集合接受 LINQ 语句中的表达式。.

注意滥用药物!

AsEnumerable像药物一样工作。这是一个快速修复,但需要付出代价,并且不能解决根本问题。

在许多 Stack Overflow 答案中,我看到人们申请AsEnumerable解决几乎所有与 LINQ
表达式中不受支持的方法有关的问题。但价格并不总是很清楚。例如,如果您这样做:

context.MyLongWideTable // A table with many records and columns       .Where(x => x.Type == "type")       .Select(x => new { x.Name, x.CreateDate })

…所有内容都被巧妙地转换为 过滤 ( Where) 和 项目 ( Select) 的 SQL 语句。也就是说,SQL
结果集的长度和宽度都被分别减小了。

现在假设用户只想查看CreateDate. 在实体框架中,您会很快发现…

.Select(x => new { x.Name, x.CreateDate.Date })

…不支持(在撰写本文时)。啊,幸运的是有AsEnumerable修复:

context.MyLongWideTable.AsEnumerable()       .Where(x => x.Type == "type")       .Select(x => new { x.Name, x.CreateDate.Date })

当然,它可能会运行。但它将整个表拉入内存,然后应用过滤器和预测。好吧,大多数人都足够聪明,可以做到第Where一个:

context.MyLongWideTable       .Where(x => x.Type == "type").AsEnumerable()       .Select(x => new { x.Name, x.CreateDate.Date })

但是仍然首先获取所有列,并且投影是在内存中完成的。

真正的解决办法是:

context.MyLongWideTable       .Where(x => x.Type == "type")       .Select(x => new { x.Name, DbFunctions.TruncateTime(x.CreateDate) })

(但这需要更多的知识......)

这些方法不能做什么?

恢复 IQueryable 功能

现在有一个重要的警告。当你这样做

context.Observations.AsEnumerable()                    .AsQueryable()

您最终会得到表示为的源对象IQueryable。(因为这两种方法都只转换而不转换)。

但是当你这样做时

context.Observations.AsEnumerable().Select(x => x)                    .AsQueryable()

结果会是什么?

Select产生WhereSelectEnumerableIterator一个. 这是一个内部 .Net 类,它实现IEnumerable
而不是IQueryable. 因此,已经发生了到另一种类型的转换,并且后续AsQueryable将永远无法返回原始源。

这意味着 usingAsQueryable不是 一种将 具有特定功能的查询提供程序神奇地注入可枚举的方法。假设你这样做

var query = context.Observations.Select(o => o.Id)                   .AsEnumerable().Select(x => x.ToString())                   .AsQueryable()                   .Where(...)

where 条件永远不会被翻译成 SQL。AsEnumerable()紧随其后的 LINQ 语句明确切断了与实体框架查询提供程序的连接。

我特意展示了这个例子,因为我在这里看到了一些问题,例如人们试图Include通过调用将功能“注入”到集合中AsQueryable。它编译并运行,但它什么也不做,因为底层对象不再有Include实现。

执行

两者都不执行(或AsQueryable枚举
源对象。他们只改变他们的类型或表示。所涉及的接口和都不过是“等待发生的枚举”。它们在被迫执行之前不会被执行,例如,如上所述,通过调用.AsEnumerable
__IQueryable``IEnumerable``ToList()

这意味着执行IEnumerable通过调用对象获得AsEnumerable的.IQueryable将执行底层的IQueryable.
随后的执行IEnumerable将再次执行IQueryable. 这可能非常昂贵。

具体实现

到目前为止,这只是关于Queryable.AsQueryableEnumerable.AsEnumerable扩展方法。但当然,任何人都可以编写具有相同名称(和函数)的实例方法或扩展方法。

实际上,特定AsEnumerable扩展方法的一个常见示例是DataTableExtensions.AsEnumerable.
DataTable没有实现IQueryableor IEnumerable,所以常规的扩展方法不适用。

Asp.net MVC 中利用jquery datatables 实现数据分页显示功能

Asp.net MVC 中利用jquery datatables 实现数据分页显示功能

1、Controller中的方法代码如下:

由于方法中的存储过程没有带分页参数,所以还可以有继续优化的空间。

/// <summary>
    /// 获取测点列表
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    public JsonResult GetMeasurePointList(string TreeID, string TreeType, int sEcho, int iDisplayStart, int iDisplayLength)
    {
      DataTable dtResult = new DataTable();
      string sql = string.Format("EXEC P_GET_ZXJG_TagList ''{0}'',''{1}''", TreeID, TreeType);
      dtResult = QuerySQL.GetDataTable(sql);
      dtResult.Columns.Add("XuHao", typeof(string));
      dtResult.Columns.Add("StrValueTime", typeof(string));
      for (int i = 0; i < dtResult.Rows.Count; i++)
      {
        dtResult.Rows[i]["XuHao"] = (i + 1).ToString();
        dtResult.Rows[i]["StrValueTime"] = Convert.ToDateTime(dtResult.Rows[i]["F_ValueTime"]).ToString("yyyy-MM-dd HH:mm:ss");
      }
      int iTotalRecords = 0;
      int iTotalDisplayRecords = 0;
      List<DataRow> queryList = dtResult.AsEnumerable().ToList();
      iTotalRecords = queryList.Count();
      queryList = queryList.Skip(iDisplayStart).Take(iDisplayLength).ToList();
      iTotalDisplayRecords = queryList.Count();
      var temp = from p in queryList
            select new
            {
              XuHao = p.Field<string>("XuHao").ToString(),
              F_Description = p.Field<string>("F_Description").ToString(),
              StrValueTime = p.Field<string>("StrValueTime").ToString(),
              F_Value = p.Field<decimal>("F_Value").ToString(),
              F_Unit = p.Field<string>("F_Unit").ToString(),
              F_AlmLow = p.Field<decimal>("F_AlmLow").ToString(),
              F_AlmUp = p.Field<decimal>("F_AlmUp").ToString()
            };
      return Json(new
        {
          draw = sEcho,
          recordsFiltered = iTotalRecords,
          recordsTotal = iTotalDisplayRecords,
          data = temp.ToList()
        }, JsonRequestBehavior.AllowGet);
    }

2、cshtml视图页面中代码如下:

function InitData() {
    var dataTable = $(''#tbMeasurePointList'').DataTable({
      "scrollY": "hidden",
      "scrollCollapse": false,
      "dom": ''tr<"bottom"lip><"clear">'',
      language: {
        lengthMenu: '''',//左上角的分页大小显示。
        search: ''<span>搜索:</span>'',//右上角的搜索文本,可以写html标签
        loadingRecords: ''数据加载中...'',
        paginate: {
          //分页的样式内容。
          previous: "上一页",
          next: "下一页",
          first: "",
          last: ""
        },
        zeroRecords: "暂无数据",//table tbody内容为空时,tbody的内容。
        //下面三者构成了总体的左下角的内容。
        info: "<spanpagesStyle''>总共<spanrecordsStyle''> _TOTAL_ 条,计 _PAGES_ </span>页,当前显示 _START_ -- _END_ 条记录 </span>",//左下角的信息显示,大写的词为关键字。初始_MAX_ 条 
        infoEmpty: "0条记录",//筛选为空时左下角的显示。
        infoFiltered: ""//筛选之后的左下角筛选提示,
      },
      "lengthChange": false,
      "ordering": false,
      "iDisplayLength": 10,
      "searching": false,
      destroy: true, //Cannot reinitialise DataTable,解决重新加载表格内容问题 
      "serverSide": true,
      "sAjaxSource": "@Url.Action("GetMeasurePointList", "OnlineMonitor")",
      "fnServerData": function (sSource, aoData, fnCallback) {
        aoData.push({ "name": "TreeID", "value": $("#hidTreeID").val() });
        aoData.push({ "name": "TreeType", "value": $("#hidTreeType").val() });
        $.ajax({
          "dataType": ''json'',
          "type": "POST",
          "url": sSource,
          "data": aoData,
          "success": fnCallback
        });
      },
      "aoColumns": [
        { "mDataProp": "XuHao", "width": "50" },
        { "mDataProp": "F_Description", "width": "400" },
        { "mDataProp": "StrValueTime", "width": "200" },
        { "mDataProp": "F_Value", "width": "100" },
        { "mDataProp": "F_Unit", "width": "100" },
        { "mDataProp": "F_AlmLow", "width": "100" },
        { "mDataProp": "F_AlmUp", "width": "100"}
      ],
      "createdRow": function (row, data, index) {
        $(row).children(''td'').eq(0).attr(''style'', ''text-align: center;'');
        $(row).children(''td'').eq(1).attr(''style'', ''text-align: left;'');
        $(row).children(''td'').eq(2).attr(''style'', ''text-align: center;'');
        $(row).children(''td'').eq(3).attr(''style'', ''text-align: right;'');
        $(row).children(''td'').eq(4).attr(''style'', ''text-align: center;'');
        $(row).children(''td'').eq(5).attr(''style'', ''text-align: right;'');
        $(row).children(''td'').eq(6).attr(''style'', ''text-align: right;'');
      }
    });
  }

3、实际显示效果如下图所示:

以上所述是小编给大家介绍的Asp.net MVC 中利用jquery datatables 实现数据分页显示,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

您可能感兴趣的文章:
  • ASP.NET MVC 5使用X.PagedList.Mvc进行分页教程(PagedList.Mvc)
  • MVC+jQuery.Ajax异步实现增删改查和分页
  • MVC分页之MvcPager使用详解
  • ASP.NET MVC分页的实现方法
  • ASP.NET MVC分页和排序功能实现
  • ASP.NET MVC5 实现分页查询的示例代码
  • ASP.NET MVC4 HtmlHelper扩展类,实现分页功能
  • ASP.NET MVC4 Razor模板简易分页效果
  • ASP.NET MVC+EF在服务端分页使用jqGrid以及jquery Datatables的注意事项
  • MVC使用MvcPager实现分页效果

今天关于asp.net – 可以手动将OData参数应用于`.AsQueryable()`的结果?的介绍到此结束,谢谢您的阅读,有关.NET Core - IEnumerable 与 IQueryable 中产生的不同空间/地理结果、.net 手动建DataTable 获取DataTable列名 修改DataTable 列的顺序、.ToList()、.AsEnumerable()、AsQueryable() 之间有什么区别?、Asp.net MVC 中利用jquery datatables 实现数据分页显示功能等更多相关知识的信息可以在本站进行查询。

本文标签: