2

我在 SQL Azure 中使用实体框架,在我的应用程序的一页中,我们向用户展示了相当多的相关数据。我们在页面上最多加载 30 个项目,但每个项目都有 5 个与其他对象的一对多映射。查询时间处于合理水平,但我在对象映射上泄露了相当多的性能。(几乎整整一秒)。

这是我的对象的示例

public class Task
{
    public string Name {get; set;}
    public string Status {get; set;}
    public DateTime DueDate {get; set;}
    public IEnumerable<TaskData> Data {get; set;}
    public IEnumerable<Transaction> Transactions {get; set;}
    public IEnumerable<File> Files {get; set;}
    public IEnumerable<Comment> Comments {get; set;}
    public IEnumerable<People> People {get; set;}
}

任务具有名称、状态和截止日期。它还有许多自定义名称/值对的任务数据、许多显示任务历史的事务、许多文件、许多评论和许多工作人员。

我的 EF 查询看起来像这样。

var Items = context.Items.Include(x=>x.Data).Include(x=>x.Files).Include(x=>x.Comments).Include(x=>x.People).Where(some constraint).ToList();

特定任务的相关性首先基于状态,然后基于截止日期。所以我创建了一个 IComparable 覆盖以用于排序。关键是分页查询在这种情况下不能很好地工作,因为排序不是基于 int 或日期(对吗?)

在我们应用程序的其余部分中,我们显示的关于每个任务的信息较少,并且 Linq2Entities 工作得很好。在这种情况下,对象映射正在杀死我们。我已经走上了使用 Dapper 直接进入数据库的道路,但一对多映射有它的警告。对于一些关系,我认为它会运作良好,但不适用于 5-6。我接下来要看的是 PetaPoco,但没走多远,我就想我最好先把这个问题放在这里。

我是否因为试图带回这么多数据而疯狂?我有哪些选择可以从中获得最大性能?因为它只是应用程序的一个领域,所以我会稍微复杂一点。

4

1 回答 1

2

我敢打赌,您的 EF 查询正在拉回太多数据。问题是,“最佳”检索技术在很大程度上取决于所提取数据的类型和数量。

预先了解这一点可以让您根据预期的数据集调整您运行的查询。

例如......如果您只提取有限数量的具有大量子实体的实体,那么我在这里编写的模式效果很好:

如何使用 Dapper 映射嵌套对象列表

如果您知道要提取的 id 并且少于 2000 个,则可以通过查询单个网格并使用以下方法进行映射来简化所有操作QueryMultiple

cnn.QueryMultiple(@"select * from Tasks where Id in @ids 
select * from Files where TaskId in @ids
.. etc ..", new {ids = new int[] {1,2,3}});

如果您要拉出更大的集合,您可能需要进行批处理,或者分阶段进行。


对于您的特定示例,我将查询Tasks以获取所有任务 ID 和数据,然后使用单个映射QueryMultiple到所有关联表的关系。

于 2011-09-26T06:17:37.817 回答