1

I have an ASP.NET MVC 3 project using .NET framework 4.0 and LINQ to SQL. Because I have serious problems of performance with some queries the first time they are executed I decided to use Entity Framework 5 in order to take advantage of the new LINQ auto compiled feature.

Now I have installed VS 2012, .NET framework 4.5 and Entity Framework 5 and changed my project to point to the .NET framework 4.5 as well as updated my Data Context file to use EF5. The queries now have exactly the same performance, some of them are so slow at the first time execution that even I get a time out exception, the second time everything is fine, I am wondering if the problem is that maybe the migration process was not correct and I am using still the EF4 or it is just a problem of my query construction which can't use the auto compiled feature for an unknown reason.

The EntityFramework dll has the 5.0 version, and the System.Data.Entity dll the version 4, that is right, isn't? Any suggestions?

I include the most problematic query, it retrieves paginated the result for a grid (Telerik MVC grid) which I need to build through 2 queries (originally was a SQL sentence with a sub query):

     /// <summary>
    /// Get the elements for the AppLog grid.
    /// </summary>
    public void GetAppLogElements(
        int clientID, string language, int functionID, int errorLevel,
        int numPage, int pageSize, IList<IFilterDescriptor> filterDescriptors, IList<SortDescriptor> sortDescriptors, IList<GroupDescriptor> groupDescriptors,
        ref IQueryable<Model_AppLog> rows, ref int numRows)
    {
        string orderString = string.Empty;

        var items =
            from ap in objDataContext.applicationLogs
            where
                ap.clientID == clientID &&
                ap.recordGroup != null
            join alf in objDataContext.appLogFunctions on
                new { functionID = ap.functionID.Value } equals new { functionID = alf.functionID }
            join ale in objDataContext.appLogErrorLevels on
                new { errorLevel = ap.errorLevel.Value } equals new { errorLevel = ale.errorLevelID }
            join als in objDataContext.appLogSeverities on
                new { severity = ap.severity.Value } equals new { severity = als.severityID }
            group new { ap, alf, als } by new { ap.functionID, ap.recordGroup, ap.clerkID } into queryGrouped
            select new Model_AppLog()
            {
                sequence = queryGrouped.Max(c => c.ap.sequence),
                functionID = queryGrouped.Key.functionID,
                recordGroup = queryGrouped.Key.recordGroup,
                clerkID = queryGrouped.Key.clerkID,
                date = queryGrouped.Min(c => c.ap.date),
                errorLevel = (queryGrouped.Max(c => c.ap.errorLevel) == null || !queryGrouped.Max(c => c.ap.errorLevel).HasValue ? 0 : queryGrouped.Max(c => c.ap.errorLevel)),
                severity = queryGrouped.Max(c => c.ap.severity)
            };            

        if (errorLevel != -1)
            items = items.Where(column => column.errorLevel >= errorLevel);

        var _items =
            from subSelect in items
            join alf in objDataContext.appLogFunctions on
                new { functionID = subSelect.functionID.Value } equals new { functionID = alf.functionID }
            join alft in objDataContext.appLogFunctionTexts on
                new { alf.functionID, language } equals new { alft.functionID, alft.language }
            join ale in objDataContext.appLogErrorLevels on
                new { errorLevel = subSelect.errorLevel.Value } equals new { errorLevel = ale.errorLevelID }
            join alet in objDataContext.appLogErrorLevelTexts on
                new { errorLevelID = subSelect.errorLevel.Value, language } equals new { alet.errorLevelID, alet.language }
            join als in objDataContext.appLogSeverities on
                new { severity = subSelect.severity.Value } equals new { severity = als.severityID }
            join alst in objDataContext.appLogSeverityTexts on
                new { als.severityID, language } equals new { alst.severityID, alst.language }
            select new Model_AppLog()
            {
                sequence = subSelect.sequence,
                functionID = subSelect.functionID,
                recordGroup = subSelect.recordGroup,
                clerkID = subSelect.clerkID,
                date = subSelect.date,
                errorLevel = subSelect.errorLevel,
                severity = subSelect.severity,
                functionDescription = alft.denotation,
                errorLevelDescription = alet.denotation,
                severityDescription = alst.denotation
            };                     

        //Apply filters
        if (filterDescriptors != null && filterDescriptors.Any())
        {
            _items = _items.Where(ExpressionBuilder.Expression<Model_AppLog>(filterDescriptors));
        }

        if (functionID != -1)            
            _items = _items.Where(column => column.functionID == functionID);                              

        //Apply sorting        
        if (sortDescriptors != null)
        {
            GlobalMethods objGlobalMethods = new GlobalMethods();
            orderString = objGlobalMethods.GetOrderString(sortDescriptors);
        }

        //Apply ordering
        if (orderString != string.Empty)            
            _items = _items.OrderBy(orderString);            
        else            
            _items = _items.OrderByDescending(x => x.date);            

        //Set total number of rows
        numRows = _items.AsEnumerable<Model_AppLog>().Count();            

        //Get paginated results
        _items = _items.Skip(pageSize * (numPage - 1)).Take(pageSize);            

        //Set data result            
        rows = _items;
    }
4

1 回答 1

1

这是一篇关于 EF 性能的论文:MSDN

改善启动时间的最重要的事情是预编译您的视图(在 MSDN 论文末尾附近有一个部分)

如果您首先使用数据库,则here可以使用 T4 模板。

如果您先使用代码,则有一个项目here,尽管我自己没有尝试过。


注意:当您将项目从 .NET 4.0 升级到 .NET 4.5 时,您必须卸载 EF NuGet 包并重新安装它 - 不同的运行时有不同的 EF 5 版本。

于 2013-01-14T09:15:39.430 回答