实体框架 4 - 列表基于 T 的子属性的 Order By
我有以下代码 -
public void LoadAllContacts()
{
var db = new ContextDB();
var contacts = db.LocalContacts.ToList();
grdItems.DataSource = contacts.OrderBy(x => x.Areas.OrderBy(y => y.Name));
grdItems.DataBind();
}
我试图根据每个联系人中包含的区域名称对联系人列表进行排序。当我尝试上述操作时,我得到“至少一个对象必须实现 IComparable”。有没有一种简单的方法而不是编写自定义 IComparer?
谢谢!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
试试这个:
这将在按名称对区域进行排序后,按第一个区域名称对联系人进行排序。
希望这有帮助:)
编辑:修复了代码中的错误。 (.First().名称)
try this:
this will order the contacts by the first area name, after ordering the areas by name.
Hope this helps :)
Edit: fixed error in code. (.First().Name)
我正在与 @AbdouMoumen 进行讨论,但最后我想我会提供自己的答案:-)
他的答案有效,但此代码中存在两个性能问题(都在原始问题的答案中)。
首先,代码加载数据库中的所有联系人。这可能是也可能不是问题,但一般来说我建议不要这样做。许多现代控件支持开箱即用的分页/过滤,因此您最好提供尚未评估的
IQueryable
而不是List
。但是,如果您需要内存中的所有内容,则应将ToList
延迟到最后可能的时刻。其次,在AbdouMoumen的回答中,存在所谓的“SELECT N+1”问题。默认情况下,实体框架将使用延迟加载来获取其他属性。即,在访问 Areas 属性之前,不会从数据库中获取该属性。在这种情况下,这将发生在控件“
for
循环”中,同时它按名称对结果集进行排序。打开 SQL Server Profiler 看看我的意思:您将看到所有联系人的 SELECT 语句,以及每个联系人的附加 SELECT 语句,用于获取该联系人的区域。
更好的解决方案如下:
I was in a discussion with @AbdouMoumen but in the end I thought I'd provide my own answer :-)
His answer works, but there two performance issues in this code (both in the answer as in the original question).
First, the code loads ALL contacts in the db. This may or may not be a problem, but in general I would recommend NOT to do this. Many modern controls support paging/filtering out of the box, so you'd be better off supplying an not-yet-evaluated
IQueryable<T>
instead ofList<T>
. If however you need everything in memory, you should delay theToList
to the last possible moment.Second, in AbdouMoumen's answer, there is a so-called 'SELECT N+1' problem. Entity Framework will by default use lazy loading to fetch additional properties. I.e. the Areas property will not be fetched from the database until it's accessed. In this case this will happen in the controls '
for
loop', while it's ordering the result set by name.Open up SQL Server Profiler to see what I mean: you will see a SELECT statement for all the contacts, and an additional SELECT statement for each contact that fetches the Areas for that contact.
A much better solution would be the following:
是一对一的关系
(联系人->区域)
吗?如果是,请尝试以下操作:
然后
Is it one to one relation
(Contact->Area)
?if yeah then try the following :
then