实体框架是太慢了。我有什么选择?我有、慢了、实体、框架

2023-09-02 01:38:12 作者:蓅哖斑駁了誰的旧時光〃

我按照不优化prematurely的口号和codeD了使用实体框架我的WCF服务。

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

不过,我异形的性能和实体框架是太慢了。 (我的应用程序处理2的消息在约1.2秒,其中的(传统的)应用程序,我重新写,做在同一时间5-6消息。(旧版应用程序调用存储过程为它的数据库访问。)

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.

那么,什么是我的选择?

So, what are my options?

有没有更好的奥姆斯在那里? (东西,仅仅支持正常的阅读对象和写作和快速做吧..)

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 or Create and Update. I do very very little selecting and deleting.

推荐答案

您应该通过分析SQL命令实际上是由实体框架发出启动。根据您的配置(POCO,自跟踪实体)有很多空间的优化。您可以调试使用对象集和其中的SQL命令(这不应该调试和释放模式有所不同); T> .ToTraceString()方法。如果你遇到需要进一步优化的查询,你可以使用一些预测,以提供有关你要完成的任务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 });
}

我刚刚输入了我的头,所以这不正是它将如何执行,但EF实际上做了一些很好的优化,如果你告诉它你知道的查询(在这种情况下,一切,我们需要该分类名)。但是这不象急切装载(db.Products.Include(分类)),因为凸起可以进一步减少数据量来加载。

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.