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;
    }
Jero Lopez
  • 398
  • 1
  • 7
  • 18
  • First, to debug a performance issue, you should use SQL Profiler. Second, To migrate to EF5, you will need to add EF5.x DbContext Generator, and change a few api like "context.AddToPost --> context.Post.Add()", nothing special. – Edi Wang Jan 14 '13 at 09:13
  • Yes maybe I should also check the SQL profiler. For what do I need the "EF5.x DbContext Generator" what exactly does this kind of file? My project currently works fine without it, I just created an ADO.NET Entity Data Model and that is all. – Jero Lopez Jan 14 '13 at 12:25

1 Answers1

1

Here's a paper about EF performance: MSDN

The most important thing you can do to improve start up time is to precompile your views ( there's a section near the end of the MSDN paper )

If you're using database first, there's a T4 template here you can use.

If you're using code first, there's a project here, although I haven't tried it myself.


Note: when you upgrade your project from .NET 4.0 to .NET 4.5, you have to uninstall the EF NuGet package and reinstall it - there are different version of EF 5 for the different runtimes.

Nick Butler
  • 24,045
  • 4
  • 49
  • 70