Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Abonnements

EDM : comment contourner les problématiques liées aux bases inadéquates

Durant la formation que j'anime cette semaine, un de mes stagiaires a essayé de me coller en me donnant une base pour laquelle l'utilisation d'EF n'était, soit disant, pas possible. Heureusement, mon honneur et celui de l'EF est sauf... Smile

En effet, cette base n'est pas idéale pour EF. Elle est composée

  • d'une  table Bases avec 4 colonnes:
    • Id, int, Identity (PK)
    • Key, int, not null
    • Value, int, not null
    • Text, nvarchar

Value est un entier compris entre 1 et 9 qui ne peut plus évoluer une fois qu'il est affecté et Key est égale à  Id * 10 + Value

  • d'une table Inheriteds avec 3 colonnes:
    • Id, int, Indentity (PK)
    • Key, int, not null
    • Text2, nvarchar

Key est la même que dans la table Bases et donc, on a en réalité une relation 1 -> 0..1 entre Bases et Inheriteds même si cette relation n'existe pas en base.

  • d'une table Descriptions avec 4 colonnes:
    • Id, int, Identity (PK)
    • Key, int, not null
    • Language, nchar
    • Text, nvarchar

Key est, là aussi, la même que Bases avec une relation (non présente en base) 1 -> * entre Bases and Descriptions, comme si la PK de Descriptions était composée de Key et de Language.

Côté CSDL (description des entités), il voulait avoir :

  • une classe Base asbtraite (mappée sur Bases)
  • une classe Entity qui hérite de Base (mappée sur Inheriteds)
  • une classe Description
  • une relation 1 -> * entre Base et Description

Est-il possible de réaliser ce scénario avec EF ? Voud l'aurez compris en lisant le débit de ce post, yes we can! Smile

Comment faire cela ?

  • Tout d'abord, dans le designer, après avoir importé les tables and avoir renommer les entity types générées, il fait dupprimer la propriété Id de chacune d'entre elles.
  • Ensuite, il faut définir Base.Key, Description.Key et Description.Language comme des EntityKey.
  • Définir Base comme abstraite 
  • Supprimer Entity.Key
  • Ajouter la relation d'héritage entre Entity et Base et mettre à jour le mapping de Entity (ie: il faut mapper la colonne Key sur la propriété Base.Key)
  • Ajouter la relation entre Base et Description

Bien entendu, quand on en est là, notre EDM n'est pas correcte (rien ne permet de garantir l'intégrité des données ni l'unicité des entity keys).

Pour résoudre cela, il fait changer le SSDL (description de la BD) et simuler une base "idéale" sans Id avec Key comme PK).

Comme Key est calculée, il faut changer son StoreGeneratedPattern et le passé à Computed.

Ensuite, il faut gérer les opérations CUD de la base sur Base car il faut calculer la KeyValue.

Base étant abstraite donc il faut définir les opérations CUD pour ses entity types héritées (Entity dans notre cas).

<EntityContainer Name="TestModelStoreContainer">

    <EntitySet Name="Bases" EntityType="TestModel.Store.Bases" store:Type="Tables" Schema="dbo" />

    <EntitySet Name="Descriptions" EntityType="TestModel.Store.Descriptions" store:Type="Tables" Schema="dbo" />

    <EntitySet Name="Inheriteds" EntityType="TestModel.Store.Inheriteds" store:Type="Tables" Schema="dbo" />

</EntityContainer>

<EntityType Name="Bases">

    <Key>

        <PropertyRef Name="Key" />

    </Key>

    <!--<Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />-->

    <Property Name="Key" Type="int" Nullable="false" StoreGeneratedPattern="Computed" />

    <Property Name="Value" Type="int" Nullable="false" />

    <Property Name="Text" Type="nvarchar" MaxLength="50" />

</EntityType>

<EntityType Name="Descriptions">

    <Key>

        <PropertyRef Name="Key" />

        <PropertyRef Name="Language" />

    </Key>

    <!--<Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />-->

    <Property Name="Key" Type="int" Nullable="false" />

    <Property Name="Language" Type="nchar" Nullable="false" MaxLength="20" />

    <Property Name="Text" Type="nvarchar" MaxLength="50" />

</EntityType>

<EntityType Name="Inheriteds">

    <Key>

        <PropertyRef Name="Key" />

    </Key>

    <!--<Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />-->

    <Property Name="Key" Type="int" Nullable="false" StoreGeneratedPattern="Computed" />

    <Property Name="Text2" Type="nvarchar" MaxLength="50" />

</EntityType>

 

<Function Name="InsertEntity" IsComposable="false">

    <CommandText>

        INSERT INTO Bases

        ([Key], Value ,[Text])

        VALUES

        (-1, @Value, @Text)

 

        DECLARE @IdValue int

        SET @IdValue = SCOPE_IDENTITY()

 

        DECLARE @KeyValue int

        SET @KeyValue = @IdValue * 10 + @Value

 

        UPDATE Bases

        SET [Key] = @KeyValue

        WHERE Id = @IdValue

 

        INSERT INTO Inheriteds

        ([Key], Text2)

        VALUES

        (@KeyValue, @Text2)

 

        SELECT @KeyValue AS KeyValue

    </CommandText>

    <Parameter Name="Value" Type="int" />

    <Parameter Name="Text" Type="nvarchar" MaxLength="50" />

    <Parameter Name="Text2" Type="nvarchar" MaxLength="50" />

</Function>

<Function Name="UpdateEntity" IsComposable="false">

    <CommandText>

        UPDATE Bases

        SET [Text] = @Text

        WHERE [Key] = @Key

 

        UPDATE Inheriteds

        SET Text2 = @Text2

        WHERE [Key] = @Key

    </CommandText>

    <Parameter Name="Key" Type="int" />

    <Parameter Name="Text" Type="nvarchar" MaxLength="50" />

    <Parameter Name="Text2" Type="nvarchar" MaxLength="50" />

</Function>

<Function Name="DeleteEntity" IsComposable="false">

    <CommandText>

        DELETE Inheriteds

        WHERE [Key] = @Key

 

        DELETE Bases

        WHERE [Key] = @Key

    </CommandText>

    <Parameter Name="Key" Type="int" />

</Function>

Maintenant, il ne reste plus qu'à définir le mapping de l'entity type Entity avec  mes SSDL functions:

<EntitySetMapping Name="BaseSet">

    <EntityTypeMapping TypeName="IsTypeOf(TestModel.Base)">

        <MappingFragment StoreEntitySet="Bases">

            <ScalarProperty Name="Key" ColumnName="Key" />

            <ScalarProperty Name="Value" ColumnName="Value" />

            <ScalarProperty Name="Text" ColumnName="Text" />

        </MappingFragment>

    </EntityTypeMapping>

    <EntityTypeMapping TypeName="TestModel.Entity">

        <MappingFragment StoreEntitySet="Inheriteds">

            <ScalarProperty Name="Key" ColumnName="Key" />

            <ScalarProperty Name="Text2" ColumnName="Text2" />

        </MappingFragment>

        <ModificationFunctionMapping>

            <InsertFunction FunctionName="TestModel.Store.InsertEntity">

                <ScalarProperty Name="Value" ParameterName="Value"/>

                <ScalarProperty Name="Text" ParameterName="Text"/>

                <ScalarProperty Name="Text2" ParameterName="Text2"/>

                <ResultBinding Name="Key" ColumnName="KeyValue"/>

            </InsertFunction>

            <UpdateFunction FunctionName="TestModel.Store.UpdateEntity">

                <ScalarProperty Name="Key" ParameterName="Key" Version="Current"/>

                <ScalarProperty Name="Text" ParameterName="Text" Version="Current"/>

                <ScalarProperty Name="Text2" ParameterName="Text2" Version="Current"/>

            </UpdateFunction>

            <DeleteFunction FunctionName="TestModel.Store.DeleteEntity">

                <ScalarProperty Name="Key" ParameterName="Key"/>

            </DeleteFunction>

        </ModificationFunctionMapping>

    </EntityTypeMapping>

</EntitySetMapping>

Mon modèle est maintenant valide. Je peux avoir une bonne conception de mes entités sans me soucier des contraintes de la base.

Alors, c'est pas trop fort EF ? Moi je dis : franchement, EF, c'est trop la classe ! Smile

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Publié jeudi 29 janvier 2009 16:28 par Matthieu MEZIL

Commentaires

# re: EDM : comment contourner les problématiques liées aux bases inadéquates @ jeudi 29 janvier 2009 17:13

Merci Matthieu pour tes billets ...

Tu m'as fait plonger dans ED ... j'ai galéré au début car la base que je devais taper était tout sauf idéale ... et avec tes billets qui m'ont mis sur des pistes ... j'ai toujours réussi à obtenir ce que je voulais.

Certes, je suis persuadé que c'est loin d'être idéal et optimal ... mais ca me permet de savoir que ED a de la ressource :p

Erebuss

# re: EDM : comment contourner les problématiques liées aux bases inadéquates @ vendredi 30 janvier 2009 09:52

Merci :-)

Par contre pourquoi ED (tu travailles dans le hard discount Smile) ? soit EF soit EDM mais pas ED !

Matthieu MEZIL

# re: EDM : comment contourner les problématiques liées aux bases inadéquates @ vendredi 30 janvier 2009 09:59

LoL

C'est à cause du projet sur lequel je bosse ... il y a une partie qui est surnommée ED ...

Vivement le Weekend lol

Erebuss

# re: EDM : comment contourner les problématiques liées aux bases inadéquates @ mardi 3 février 2009 15:57

Bonjour Matthieu.

C'est vrai que c'est magnifique (c'est moi qui avait le modèle de données qui collait pas avec EF).

J'ai encore pas mal d'interrogations sur l'EF (le contraire serait étonnant vu l'étendue de l'outil...), c'était bien Julia Lerman que tu nous avais conseillé (j'ai vu qu'elle avait un bouquin sur l'EF chez O'Reilly) ?

Merci

Alexis

acoudeyras

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01