Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.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
C# 按作为实体导航属性的字段排序-Linq to Entity_C#_Linq To Entities_Sql Order By_Navigation Properties - Fatal编程技术网

C# 按作为实体导航属性的字段排序-Linq to Entity

C# 按作为实体导航属性的字段排序-Linq to Entity,c#,linq-to-entities,sql-order-by,navigation-properties,C#,Linq To Entities,Sql Order By,Navigation Properties,我有一个场景,在这个场景中,我需要在一个列上订购,该列是EF模型中用户实体的导航属性 实体: 用户-->国家1:n关系 简单的SQL查询如下所示: SELECT UserId, u.Name, c.Name FROM users u join countries c on u.CountryId = c.CountryId ORDER BY c.Name asc; 因此,我尝试使用Linq将上述SQL查询复制到实体,如下所示-(启用了延迟加载) 但是这个查询并不像上面的原生SQL查询那样返回按

我有一个场景,在这个场景中,我需要在一个列上订购,该列是EF模型中用户实体的导航属性

实体: 用户-->国家1:n关系

简单的SQL查询如下所示:

SELECT UserId, u.Name, c.Name
FROM users u join countries c on u.CountryId = c.CountryId
ORDER BY c.Name asc;
因此,我尝试使用Linq将上述SQL查询复制到实体,如下所示-(启用了延迟加载)

但是这个查询并不像上面的原生SQL查询那样返回按名称排序的“我的国家”

然而,我继续做了更多,并做了以下工作:

var enumeratedUsers = entities.users.AsEnumerable();
users = enumeratedUsers.OrderBy(fields => fields.country.Name).ToList();
但在enumeratedUser对象上订购大约50条记录大约需要7秒钟

有没有更好的方法来省略可枚举项而不返回匿名类型

谢谢

编辑


我只是忘了说EF提供程序是MySQL而不是MS SQL。事实上,我刚刚在MS SQL中的一个复制数据库上尝试了相同的查询,该查询工作正常,即国家名称的顺序正确,因此看起来除了从MySQL获取结果集并从可枚举对象的内存中执行排序外,我没有其他选择

您尝试过使用
Include

entities.users.Include["country"].OrderBy(field => field.country.Name).ToList();
这是LINQ到对象,而不是LINQ到实体

上述Order By子句将调用中定义的

也就是说,排序将在内存中完成。因此需要很长时间

编辑

这看起来像是MySQL相关的问题

你可以试试这样的

        var users = from user in entities.users
                          join country in entities.Country on user.CountryId equals country.Id
                          orderby country.Name
                          select user;
entities.users.OrderBy(field=>field.country.Name).ToList()

但此查询不会返回按本国名称排序的国家 上面的SQL查询没有

是,它不返回
国家
,只返回按国家名称排序的
用户。
执行此查询时,将以下sql发送到DB

SELECT u.*
FROM users u join countries c on u.CountryId = c.CountryId
ORDER BY c.Name asc;
如您所见,结果不包括
国家的任何字段。正如您提到的延迟加载,
countires
在需要时通过它加载。此时,
国家
按照您通过延迟加载调用的顺序进行排序。您可以通过实体集的本地属性访问
国家

这一点告诉您,如果您希望
用户
国家的名称排序,并且还希望
国家
按名称排序,那么您需要像@Dennis提到的那样急切地加载:

entities.users.Include["country"].OrderBy(field => field.country.Name).ToList();
这将转换为以下sql

SELECT u.*, c.*
FROM users u join countries c on u.CountryId = c.CountryId
ORDER BY c.Name asc;

解决方案

因为我在这两个国家和用户表中都有名为Name的列,所以执行order by country.Name时,MySQL Connector正在生成此输出:

SELECT `Extent1`.`Username`,  `Extent1`.`Name`,  `Extent1`.`Surname`, `Extent1`.`CountryId`
FROM `users` AS `Extent1` INNER JOIN `countries` AS `Extent2` ON `Extent1`.`CountryId` = `Extent2`.`CountryId`
ORDER BY `Name` ASC
因此,这将导致在users.Name而不是countries.Name上进行排序

然而,MySQL发布了6.4.3.NET connector版本,解决了一系列问题,其中之一是:

我们还包括一些与实体框架提供程序相关的SQL生成改进。资料来源:


谢谢你的所有意见。我试图尽可能清楚地帮助可能遇到我同样问题的其他人。

您没有匿名类型。在您的例子中,var关键字只是隐藏IEnumerable类型,其中TEntity是您的用户实体类型。entities.users是EntityCollection(如果我理解您的EF模型正确的话)已经实现了IEnumerable,因此您可以安全地使用entities.users.OrderBy(f=>f.country.Name).ToList();然而,正如丹尼斯所说,您必须包含所有想要的实体关联。但这并不会返回排序不规则的县名称,以查看您是否可以从该链接中获得任何信息。感谢Kornelije Petak,但那篇文章仍然在内存中排序,而不是在数据库中排序,如果他执行postData.Comments.OrderBy(c=>c.PostedDate),则在数据库中排序,至少应该在MSSQL中排序。然后,他将这些已排序的对象附加到上下文中。但是,我不知道Attach()是否对元素进行了重新排序。否则,我看不出这在内存中是如何排序的。但也许我错了。你试过了吗?我在对象上下文中启用了lazyloading…这意味着我可以省略Include,对吗?现在刚刚测试过它…事实上它返回的结果集与没有Include的结果集相同(国家名称未排序)。有没有其他方法直接在数据库上而不是在.NET对象上进行调用?@Ryan yes。不要使用
可计算的
。只需添加
orderBy
,EF将根据您的导航属性自动生成表联接和订单我刚刚编辑了我的问题。。。照你说的做根本不起作用:(已经试过了,但还是不行……我正在尝试打开SQL日志,但不知道如何:S
SELECT u.*, c.*
FROM users u join countries c on u.CountryId = c.CountryId
ORDER BY c.Name asc;
SELECT `Extent1`.`Username`,  `Extent1`.`Name`,  `Extent1`.`Surname`, `Extent1`.`CountryId`
FROM `users` AS `Extent1` INNER JOIN `countries` AS `Extent2` ON `Extent1`.`CountryId` = `Extent2`.`CountryId`
ORDER BY `Name` ASC