2

dbcontext api 似乎将导航属性设置为 ICollections (用于关联的 * 端)。获取可查询对象的正常方法(例如,如果您想要计数)似乎是

int count = dbcontext.Entry(entry).Collection(c => c.navprop).Query().Count();

但如果您想经常在数据库中过滤,那会很不方便。更重要的是,它也很容易忘记。如果有人不小心说

int count = entry.navprop.Count();

然后它获取服务器上的所有数据并在那里进行计数,这很慢。

ObjectContext 默认使用的 EntityCollection 类型也是如此。

int count = entry.navprop.CreateSourceQuery().Count();

有没有办法在模型或其他地方设置导航属性的默认集合类型是 IQueryable 或 ObjectQuery 或某种可查询类型?

请注意,这只是导航属性的问题,因为上下文中的实际对象集和数据库集项目似乎是可查询的

4

2 回答 2

1

我想出了一个解决方案,可以解决我的大部分问题。我最终做的是在我的模型中使用 ObjectContext API,并使需要很长时间才能访问私有的导航属性(用于获取和设置)。您可以通过右键单击 nav 属性在 edmx 文件中执行此操作。

然后我为包含私有导航属性的类创建了一个部分类文件,并添加了一些类似的内容。

public ObjectQuery<NavPropType> NavPropName
{
   get
   {
      if(privateNavProp != null) //in case lazy loading is disabled or something
         return privateNavProp.CreateSourceQuery();
      else
         return null;
   }
}

现在该类的任何用户都不会意外地尝试拉入所有的 navprop 项目,其中有很多。而且在 nav 属性上进行查询也很容易,而不必记住每次都调用 CreateSourceQuery。

我没有添加设置器,因为该导航属性在我的应用程序中是只读的。我确信有一种方法可以制作出适合这种模式的方法,但我对 ObjectContext API 的了解还不够,无法说明如何做到这一点。

我最终只对可能有大量数据的导航属性执行此操作,因为保留其他属性对性能没有影响。

编辑:我后来遇到的将其设为私有的一个缺点是我不能再这样做了

db.EntryTable.OrderBy(e => e.privateNavProp.Count())

即使它足够聪明,不会得到所有实体

于 2013-03-28T18:19:34.593 回答
0

不,IQueryable 不是一个集合;IQueryable 是一个接口,其实现评估针对数据源的查询(集合将是数据源)。

您可以在加载实体对象时加载计数,但是,如果内联一些无害的方法调用不是您的事:

from e in EntityA
<optional where clause for entity>
select new
{
    Entity = e,
    filteredNavPropCount = e.navprop.Where( np => <optional where clause for collection> ).Count()
}
于 2013-03-27T03:55:08.870 回答