Partage
  • Partager sur Facebook
  • Partager sur Twitter

EF méthode ADD très longue

La méthode ADD d'entityframework est très longue.

Sujet résolu
    17 décembre 2018 à 9:42:13

    Bonjour la communauté,

    Je suis en train d'implémenter EF 6.2 dans un logiciel existant via code first from database.

    Tout fonctionne parfaitement excepté la méthode ADD qui prend en moyenne 11 secondes ce qui ne me permettra pas de mettre en place EF pour des causes de performance.

    Je vous donne un exemple:

    Imports System
    Imports System.Collections.Generic
    Imports System.ComponentModel.DataAnnotations
    Imports System.ComponentModel.DataAnnotations.Schema
    Imports System.Data.Entity.Spatial
    
    Partial Public Class Adresses
        <Key>
        Public Property IdAdresse As Integer
    
        Public Property Ident_Client As Short?
    
        <StringLength(50)>
        Public Property Adresse1 As String
    
        <StringLength(50)>
        Public Property Adresse2 As String
    
        <StringLength(50)>
        Public Property Adresse3 As String
    
        <StringLength(50)>
        Public Property Adresse4 As String
    
        <StringLength(50)>
        Public Property Adresse5 As String
    
        <StringLength(50)>
        Public Property Ville As String
    
        <StringLength(5)>
        Public Property CodePays As String
    
        <StringLength(10)>
        Public Property CodePostal As String
    
        Public Property DateModif As Date?
    
        <StringLength(10)>
        Public Property Id As String
    
        <StringLength(50)>
        Public Property Codelangue As String
    
        <StringLength(50)>
        Public Property Nom As String
    End Class
    
    Imports System.Data.Entity
    Public Class CAEntities
        Inherits CAModel
        Public Sub New(ByVal Cs As String)
            MyBase.New(Cs)
        End Sub
    Public Overridable Property Adresses As DbSet(Of Adresses)
        Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder)
    Imports System.Data.Entity
    Public Class CAEntities
        Inherits CAModel
        Public Sub New(ByVal Cs As String)
            MyBase.New(Cs)
        End Sub
        Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder)
        End Sub
    End Class



    Et voici mon code d'ajout test:

                Dim contextEF As CAEntities = New CAEntities(Connection.GetConnectionString)
                Dim a As New Adresses
                a.Adresse1 = "test"
                contextEF.Adresses.Add(a)
                contextEF.SaveChanges()

    Auriez-vous une idée de la cause de cette lenteur?

    UPDATE: Je viens de m'apercevoir que cette lenteur n'est présente que sur le premier add qui correspond peut-être à l'initilisation du context alors que l'instanciation est faite en amont?

    Merci d'avance.

    -
    Edité par mimi270188 17 décembre 2018 à 9:59:00

    • Partager sur Facebook
    • Partager sur Twitter
    Si vous ne réussissez pas du premier coup, appelez ça « version 1.0 ».
      17 décembre 2018 à 12:23:20

      "code first from database"

      Gnhein?!? o_O

      C'est la première fois que je la vois celle là tient XD

      Soit c'est code-first (tu développes d'abord en C# et la base de données est créée depuis ce modèle de données C#), soit c'est database-first (la base de données est déjà en place et le code C# est généré à partir du schéma de base de données), mais "code-first database", sauf erreur de ma part, ça n'existe pas ^^ . Il existe aussi le model-first, où "un designer" (souvent graphique) vient générer les 2 (le code C# d'un côté et les scripts SQL de mise en de place de la BdD de l'autre).

      "Je viens de m'apercevoir que cette lenteur n'est présente que sur le premier add qui correspond peut-être à l'initilisation du context alors que l'instanciation est faite en amont?"

      C'est exactement là où j'allais en venir : S'agissait-il d'une lenteur constante ou d'une lenteur uniquement au 1er essai ?

      Donc...EF, quand tu as ton code et la base de données de l'autre, va créer des objet-proxy qui héritent de tes entités. Ce sont ces proxies qui sont chargés de rattacher les entités entres elle et avec un contexte (qui, lui même, référence la base de données).

      Ces objet-proxy sont stockés, pour des raisons de performances, dans une assembly dynamiquement générée par défaut.

      Le contrecoup de ça, c'est que lors du premier usage de ton modèle d'entité, il faut quand même du temps pour générer cette assembly dynamique. Une fois qu'elle est en place, toute exécution sera plus rapide. Lorsque le processus se termine, cette assembly dynamique est détruite. La prochaine 1ere exécution sera donc toujours lente.

      Et comme les gars derrière EF ont quand même pensé à beaucoup de choses, il est possible de pré-générer cette assembly dynamique, pour qu'elle ne soit plus dynamique ^^ . Clic ici pour les différentes techniques. Dans ton cas, les points 1 & 2 sont intéressants. Le point 3 est plus généralement applicable à toute application .NET, il consiste en la génération de binaire partiellement statiquement liés, à partir des assemblies managées, liées dynamiquement. Teste d'abord uniquement les points 1 & 2. Tu devrais déjà constater un gain de performances notable, sans avoir besoin du point 3.

      -
      Edité par Nisnor 17 décembre 2018 à 17:13:35

      • Partager sur Facebook
      • Partager sur Twitter
        17 décembre 2018 à 16:12:58

        Bonjour Nisnor,

        Merci beaucoup pour ta réponse c'est exactement ce que je cherchai.

        Et concernant Code First from database:

        • Partager sur Facebook
        • Partager sur Twitter
        Si vous ne réussissez pas du premier coup, appelez ça « version 1.0 ».
          19 décembre 2018 à 14:13:58

          Re,

          En fin de compte je tente depuis 2 jours de mettre en place la technique numéro 1 sans succès. Voici mon code:

          Imports System.Data.Entity
          Imports System.Data.Entity.Infrastructure
          Imports System.Data.Entity.Infrastructure.DependencyResolution
          Imports System.IO
          Imports System.Reflection
          
          <DbConfigurationType(GetType(MyContextConfiguration))>
          Public Class CAEntities
              Inherits CAModel
              Public Sub New(ByVal Cs As String)
                  MyBase.New(Cs)
              End Sub
              Public Sub New()
                  MyBase.New()
              End Sub
              Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder)
          
              End Sub
          End Class
          Public Class MyContextConfiguration
              Inherits DbConfiguration
              Public Sub MycontectConfiguration()
                  Dim cachedDbModelStore As MyDbModelStore = New MyDbModelStore("C:\Users\mgrandiere.COMMANDALKON\source\repos\ConsoleApp1VB\ConsoleApp1VB\EFCache\")
                  Dim dependencyResolver As IDbDependencyResolver = New SingletonDependencyResolver(Of DbModelStore)(cachedDbModelStore)
                  AddDependencyResolver(dependencyResolver)
              End Sub
          
              Public Class MyDbModelStore
                  Inherits DefaultDbModelStore
          
                  Sub New(location As String)
                      MyBase.New(location)
                  End Sub
          
                  Public Overrides Function TryLoad(contextType As Type) As DbCompiledModel
                      Dim path As String = GetFilePath(contextType)
                      If System.IO.File.Exists(path) Then
                          Dim lastWriteTime As DateTime = File.GetLastWriteTimeUtc(path)
                          Dim lastWriteTimeDomainAssembly = File.GetLastWriteTimeUtc(Assembly.GetExecutingAssembly.CodeBase)
                          If lastWriteTime > lastWriteTimeDomainAssembly Then
                              File.Delete(path)
                          End If
                      End If
          
                      Return MyBase.TryLoad(contextType)
                  End Function
          
              End Class
          End Class

          Mais lorsque j'utilise mon context à la première utilisation j'ai toujours exactement la même lenteur.

          Concernant la technique 2 j'ai utilisé:

          Entity Framework 6 Power Tools Community Edition qui m'a bien créé les vues de mon modèle mais j'y ai perdu en performance :(

          Quelqu'un aurai une idée?

          • Partager sur Facebook
          • Partager sur Twitter
          Si vous ne réussissez pas du premier coup, appelez ça « version 1.0 ».
            27 février 2019 à 15:56:33

            C'est bon j'ai trouvé la solution suivante qui améliore énormément mes lancements d'application:

            Imports System.Data.Entity
            Imports System.Data.Entity.Infrastructure
            <DbConfigurationType(GetType(MyDbConfiguration))>
            Public Class CAEntities
                Inherits CAModel
                Public Sub New(ByVal Cs As String)
                    MyBase.New(Cs)
                End Sub
                Public Sub New()
                    MyBase.New()
                End Sub
            
                Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder)
            
                End Sub
            End Class
            Public Class MyDbConfiguration
                Inherits DbConfiguration
                Public Sub New()
                    Dim path As String = System.IO.Path.GetDirectoryName(Me.GetType.Assembly.Location)
                    SetModelStore(New DefaultDbModelStore(path))
                End Sub
            End Class



            -
            Edité par mimi270188 27 février 2019 à 15:56:51

            • Partager sur Facebook
            • Partager sur Twitter
            Si vous ne réussissez pas du premier coup, appelez ça « version 1.0 ».

            EF méthode ADD très longue

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown