Asp.net mvc EF&;剃刀使未使用的柱远离电线

Asp.net mvc EF&;剃刀使未使用的柱远离电线,asp.net-mvc,entity-framework,razor,Asp.net Mvc,Entity Framework,Razor,我正在使用ASP.NETMVC3、Razor和实体框架开发一个页面。我使用nuget获取mini profiler,我注意到SQL调用正在查询所有列。我意识到发生这种情况是因为我将scaffold'ed视图与IEnumerable一起使用,所以我的控制器返回视图(Type.ToList()) 我下意识的反应是使用linq只选择我需要的列并将它们放入列表,但这样我就失去了我的“强”EF类型和它们的优点,比如导航属性 是否可以指示EF仅返回所查询表中某一列子集的数据?您可以将其更改为将列表保留为IQ

我正在使用ASP.NETMVC3、Razor和实体框架开发一个页面。我使用nuget获取mini profiler,我注意到SQL调用正在查询所有列。我意识到发生这种情况是因为我将scaffold'ed视图与IEnumerable一起使用,所以我的控制器返回视图(Type.ToList())

我下意识的反应是使用linq只选择我需要的列并将它们放入列表,但这样我就失去了我的“强”EF类型和它们的优点,比如导航属性


是否可以指示EF仅返回所查询表中某一列子集的数据?

您可以将其更改为将列表保留为IQueryable(只需删除
.ToList()
),然后在视图中进行选择。由于SQL查询的执行将推迟到枚举结果时,因此在视图中添加的任何过滤器都将优化查询。但这取决于你如何看待它,这会给关注点的分离带来麻烦

您的视图代码将变成:

@model IQueryable<SomeType>
<ul>
@for(var item in Model.Select(x => new { x.Property1, x.Property2 })) {
    <li>@item.Property1</li>
}
</ul>
@model IQueryable
    @for(Model.Select中的var项(x=>new{x.Property1,x.Property2})){
  • @项目1.财产1
  • }
如果采用这种方法,您需要在视图中非常小心,以确保不会多次枚举IQueryable(从而产生额外的数据库查询并抵消任何性能优势)


最安全的方法是为每个视图创建一个自定义视图模型并将其投影到该视图中,但这并不能真正回答您的问题。

您可以将其更改为将列表保留为IQueryable(只需删除
.ToList()
),然后在视图中进行选择。由于SQL查询的执行将推迟到枚举结果时,因此在视图中添加的任何过滤器都将优化查询。但这取决于你如何看待它,这会给关注点的分离带来麻烦

您的视图代码将变成:

@model IQueryable<SomeType>
<ul>
@for(var item in Model.Select(x => new { x.Property1, x.Property2 })) {
    <li>@item.Property1</li>
}
</ul>
@model IQueryable
    @for(Model.Select中的var项(x=>new{x.Property1,x.Property2})){
  • @项目1.财产1
  • }
如果采用这种方法,您需要在视图中非常小心,以确保不会多次枚举IQueryable(从而产生额外的数据库查询并抵消任何性能优势)


最安全的方法是为每个视图创建一个自定义视图模型并将其投影到该视图中,但这并不能真正回答您的问题。

这就是问题的关键:要么使用所有属性加载实体,要么通过投影到非实体的自定义或匿名类型来提高加载性能。投影完全在您的控制之下,因此您必须选择要加载的实体,甚至是相关数据。如果您可以在加载实体的同时遵守数据库约束、null和referential(如导航属性所需),同时忽略不需要的列,这不是很好吗?我知道,在这种情况下这是小菜一碟,但我通常希望表的一小部分具有EF优势。这就是问题的关键:要么使用所有属性加载实体,要么通过投影到非实体的自定义或匿名类型来提高加载性能。投影完全在您的控制之下,因此您必须选择要加载的实体,甚至是相关数据。如果您可以在加载实体的同时遵守数据库约束、null和referential(如导航属性所需),同时忽略不需要的列,这不是很好吗?我知道,这是一个蛋糕,吃它太多的情况下,但我经常希望EF的好处,为一个非常小的子集表。感谢您的回应。我现在投了更高的票,因为它看起来是正确的。我还没有机会尝试它,一旦我确认它有效,我会将此标记为答案:-)感谢您的回复。我现在投了更高的票,因为它看起来是正确的。我还没有机会尝试它,一旦我确认它有效,我会将此标记为答案:-)