实体框架太慢.我有哪些选择? [英] Entity Framework is Too Slow. What are my options?

查看:25
本文介绍了实体框架太慢.我有哪些选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循了不要过早优化"的原则,并使用实体框架编写了我的 WCF 服务.

I have followed the "Don't Optimize Prematurely" mantra and coded up my WCF Service using Entity Framework.

但是,我分析了性能和实体框架太慢了.(我的应用程序在大约 1.2 秒内处理 2 条消息,其中我正在重写的(旧版)应用程序同时处理 5-6 条消息.(旧版应用程序为其数据库访问调用 sproc.)

However, I profiled the performance and Entity Framework is too slow. (My app processes 2 messages in about 1.2 seconds, where the (legacy) app that I am re-writing does 5-6 messages in the same time. (The legacy app calls sprocs for its DB Access.)

我的分析指出实体框架占用了每条消息的大部分时间.

My profiling points to Entity Framework taking the bulk of the time per message.

那么,我有哪些选择?

  • 有更好的 ORM 吗?
    (只支持正常读写对象并且速度很快的东西..)

  • Are there better ORMs out there?
    (Something that just supports normal reading and writing of objects and does it fast..)

有没有办法让实体框架更快?
(注意:当我说更快时,我的意思是从长远来看,而不是第一次通话.(第一次通话很慢(一条消息需要 15 秒),但这不是问题.我只需要其余消息的速度很快.)

Is there a way to make Entity Framework faster?
(Note: when I say faster I mean over the long run, not the first call. (The first call is slow (15 seconds for a message), but that is not a problem. I just need it to be fast for the rest of the messages.)

一些神秘的第三个选项,可以帮助我更快地使用我的服务.

Some mysterious 3rd option that will help me get more speed out of my service.

注意:我的大多数数据库交互都是创建和更新.我很少选择和删除.

NOTE: Most of my DB interactions are Create and Update. I do very very little selecting and deleting.

推荐答案

您应该首先分析实体框架实际发出的 SQL 命令.根据您的配置(POCO、自跟踪实体),有很大的优化空间.您可以使用 ObjectSet.ToTraceString() 方法调试 SQL 命令(在调试模式和发布模式之间应该没有区别).如果您遇到需要进一步优化的查询,您可以使用一些预测为 EF 提供有关您尝试完成的任务的更多信息.

You should start by profiling the SQL commands actually issued by the Entity Framework. Depending on your configuration (POCO, Self-Tracking entities) there is a lot room for optimizations. You can debug the SQL commands (which shouldn't differ between debug and release mode) using the ObjectSet<T>.ToTraceString() method. If you encounter a query that requires further optimization you can use some projections to give EF more information about what you trying to accomplish.

示例:

Product product = db.Products.SingleOrDefault(p => p.Id == 10);
// executes SELECT * FROM Products WHERE Id = 10

ProductDto dto = new ProductDto();
foreach (Category category in product.Categories)
// executes SELECT * FROM Categories WHERE ProductId = 10
{
    dto.Categories.Add(new CategoryDto { Name = category.Name });
}

可以替换为:

var query = from p in db.Products
            where p.Id == 10
            select new
            {
                p.Name,
                Categories = from c in p.Categories select c.Name
            };
ProductDto dto = new ProductDto();
foreach (var categoryName in query.Single().Categories)
// Executes SELECT p.Id, c.Name FROM Products as p, Categories as c WHERE p.Id = 10 AND p.Id = c.ProductId
{
    dto.Categories.Add(new CategoryDto { Name = categoryName });
}

我只是在头脑中输入了它,所以这并不是它的确切执行方式,但是如果您告诉它您对查询的所有了解(在这种情况下,我们将需要类别名称).但这不像急切加载 (db.Products.Include("Categories")),因为预测可以进一步减少要加载的数据量.

I just typed that out of my head, so this isn't exactly how it would be executed, but EF actually does some nice optimizations if you tell it everything you know about the query (in this case, that we will need the category-names). But this isn't like eager-loading (db.Products.Include("Categories")) because projections can further reduce the amount of data to load.

这篇关于实体框架太慢.我有哪些选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆