6

Używam MVC3, ASP.NET 4.5, LINQ do Entities, EF5 i SQL Server 2008 R2 i Azure (na żywo).Początkowy problem z LINQ do Entities podczas korzystania z TPH i typów złożonych, Widoki Pregen wydają się nic nie robić?

Tworzę pliki csdl, edml, msl i ssdl dla modelu w oddzielnym projekcie modelu.

Pliki te są tworzone przez dewelopera Entity z Devart, gdzie zarządzam swoim modelem podmiotu.

docelowa: Entity Framework 5

  • Lazy Loading: Włączone
  • Zobacz Generation: True
  • Validation na budowie: True
  • Metadane Artifact Przetwarzanie: Osadzanie w montażowa
  • ObjectContext jest użyte
  • Tworzenie Proxy ObjectContext Enabled: true.

Zaimplementowałem dziedziczenie TPH w moim modelu jednostki, przy czym klasa potomna składa się również z maksymalnie 10 typów złożonych (CTn).

Animal<-Cat(CT1,CT2,CT3 etc) (for example) 

Każdy typ złożony mapuje do kolumny w ogólnej tabeli zwierząt.

Moja początkowa LINQ to:

if (db.Animal.OfType<Cat>().Any(a => a.OwnerId == myOwnerId)) 

Kiedy ten prowadzony jest po raz pierwszy, może to potrwać około 40 sek, aby zakończyć. Kolejne uruchomienia trwają około 200ms.

Kiedy analizować to dodatkowo przy użyciu ORM Profiler, to daje mi kod LINQ jako:

Cat.MergeAs(0).Any(a => a.OwnerId == ((Nullable<int>)myOwnerId)) 

odkryłem wspaniałe SO pytanie pod adresem: Related SO Question, ale nie idzie wystarczająco głęboko. Chociaż zaleca aktualizację do wersji EF6, nie wspomina o nowym problemie z EF6 konieczności JIT środowiska wykonawczego EF przy pierwszym użyciu, ponieważ jest on teraz zewnętrzny dla środowiska wykonawczego .NET. Być może w późniejszej wersji EF6 tj. 6.1.2 jest to rozwiązane.

Po utworzeniu kodu T-SQL przez EF, działa on sam, bardzo szybko. Przetestowałem to w SSMS.

Więc moje pytanie, od listopada 2014 roku, składa się z:

1) W jaki sposób mogę rozwiązać początkowych opóźnień obciążenie dla mojego TPH/na terenie scenariuszu Type Próbowałem pregenerated Widoki. Widziałem odniesienia do "Złożonych zapytań".

2) Być może powinienem uaktualnić do EF6? Jednak jeśli to zrobię, czy jest już kara za JIT dla samego środowiska wykonawczego EF i jak mam to rozwiązać. Rozmieszczam w witrynach Azure.

3) W końcu zauważyłem, że inne bardziej proste zapytania korzystały z wstępnie wygenerowanych widoków, więc używam ich. To właśnie dla tego scenariusza TPH/Typu złożonego nie ma żadnego wpływu. Czy są sytuacje, w których widoki pregen nie mają żadnego wpływu?

4) Może 3) być spowodowane czasem potrzebnym do "autokompilowania zapytania", które może teraz zrobić EF5. Mając wstępnie wygenerowany widok, myślę, że to kolejne wąskie gardło. Być może ta funkcja "autokompilacji" dla złożonych elementów, takich jak moja, zajmuje dużo czasu, więc czy można zrobić aktywną ręczną kompilację? Quess to jest to, co nazywa się "CompiledQuery". Czy pisanie tego dodatkowego kodu jest istotne, czy też EF6x pomógłby mi tutaj? Mam silne przeczucie, że ten etap kompilacji zapytań jest wąskim gardłem, ale zdaję sobie również sprawę, że pisanie skompilowanych zapytań niekoniecznie jest najprostszym i łatwym do utrzymania rozwiązaniem. Obecnie mamy okresowe zadania uruchamiania, które rozgrzewają wszystkie te złożone elementy, dzięki czemu użytkownik przechodzi bezpośrednio do "trybu wykonywania gorących zapytań".

Każda pomoc w powyższym zakresie byłaby ogromnie doceniana.

Edit1

Właśnie używane JetBrains za dotTrace profil, który sięga znacznie głębiej, a to wydaje się potwierdzać, że moje gardło dzieje się z:

System.Data.Query.PlanCompiler.PreProcessor.Process(Dictionary[EdmFunctionEdmProperty[]]&) 

przy pierwszym trafieniu, że spędza 99% czas tutaj, co potwierdza mój pogląd, że miało to związek z generowaniem planu zapytania. Sposób rozwiązania tego problemu to inna sprawa.

EDIT2

mam zamiar przetestować na EF 6.1.2 po kilka dobrych rad i następuje po kursie doskonałą Julie Lerman w sprawie Pluralsight.

Odpowiedz

1

Miałem podobny problem i próbowałem różnych podejść, aby poprawić wydajność "pierwszego trafienia".

Czy zastanawiałeś się nad wdrożeniem IProcessHostPreloadClient, aby wstępnie ogrzać pamięć podręczną i nawiązać pierwsze połączenie, za pośrednictwem modelu Entity Framework, z bazą danych?

To rozwiązanie pracował dla mnie, a ja utworzyliśmy klasy PreWarmCache próbka poniżej:

namespace MyNamespace 
{ 
    public class PreWarmCache : IProcessHostPreloadClient 
    { 
     private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); 
     private readonly SystemRepository _systemRepository = new SystemRepository(); 

     public void Preload(string[] parameters) 
     { 
      // Perform initialization and cache loading logic 
      Logger.Debug("Application Started: {0}", _systemRepository.InitAppliation() ? "DB response OK" : "DB response failed"); 
     } 
    } 
} 

Check out this blog Szczegółowe informacje na temat tego, jak podłączyć się do swojego dostawcy AutoStart na IIS.

+0

dzięki za to. Spróbuję tego. Wykonuję sekwencję rozgrzewki, wywoływaną przez Pingdom, aby upewnić się, że ten obiekt pozostaje gorący. Nie idealny, ale spełnia swoją rolę. – SamJolly